Arduino DC to AC inverter VFD

Hey all,

So I am pretty new to this whole arduino electronics business but so far I've managed to make a few things to work and not blow anything up! So that's a plus.

Anyways, I am working on a project that requires me to change the frequency of an AC signal. Obviously everyone here is likely to know the standard 60Hz and 50Hz mains frequencies. I'm trying to control by variable frequency a relatively small pump motor that plugs directly into mains and runs at a standard 60Hz. I've built the electronics to convert the mains down to DC at whatever voltage. It's smooth clean power too! - Right now I've been using 12V but I can change that to anything. I've also built the switching electronics which right now is basically 2 N Chanel Fets with their Drains connected to a one leg of a 24v center tapped transformer, their gates coupled to some optoisolators/optocouplers and their source running to my DC -. With the center tap of my transformer running to my DC +. I have acquired and Arduino Mini Pro as my micro controller and have already begun experimenting!

So far I have been able to turn on my motor using square wave and a bastardization of modified sine. However, it is very loud and jumpy and just doesn't run well. Especially when using the square wave. I've been doing plenty of reading around the internet that tells me square wave is just a terrible option and that modified sine is only marginally better. So that leaves pure sine I suppose.

My question is how do I create a pure sine wave? Or at least close to a pure sine wave? I am assuming I will need to do some sort of modulated PWM signaling that controls the duty cycle of my Fets. And I would assume the ripples or harmonics created would likely be filtered out by my transformer since inducters tend to do those sorts of things. Right?

I did find a relevant PDF (Listed Below) that explain this concept and what is actually going on, but the code is way above me and I don't think I can easily modify it to work with my electronics.

http://www.csulb.edu/~hill/ee470/Lab%202d%20-%20Sine_Wave_Generator.pdf

Most of the information I find is all very similar to the examples listed in the PDF. Several forms say to do it this way because of the speed. Only thing is I need a max of like 240Hz. Nothing close to the KHz range they are shooting for. I did find a post on this form actually that I though was close to what I needed (Listed Below). I have played with it but still cant get it to function for my means.

http://forum.arduino.cc/index.php?topic=8563.0

My basic understanding here is that I need to generate 2 half cycles of these pwm sine waves on two output pins of my arduino. First the first half cycle, or the rise/fall of the sine in the V+ direction would trigger Fet 1 and then once complete the second half cycle, or the rise/fall of the sine in the V- direction would trigger Fet 2. So on and so forth.

I figure I would need 2 pins and 2 Fets because the generation of the modulated PWM is all offset in DC+.

Am I thinking correctly?

So could anyone offer some help? Links to deeper explanations of the PWM functions, tutorials, or anything really. I want to learn but I am very new at this so please bear with me. If you have any comments or suggestions I would love to hear them as well! Thanks in advance.

-Andrew.

So you want to run a 60Hz pump at 240Hz?

Okay, so I am continuing to work on some code and I think I'm beginning to grasp some of the more advanced implementations using wavetables. So a basic wave table looks as such

const uint8_t sinewave[] PROGMEM= //256 values
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};

Noticing that this contains values for both the up and down portions of the wave I "zero filled" from what appears to be the crossing point of the half cycle . Since I am assuming the beginning of the array starts with the value that is zero. Like so.

Since I don't have a scope, I am not entirely sure what this will do... Time to go grab a speaker or something.

const uint8_t sinewave[] PROGMEM= //256 values
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
};

But my goal was to alternate between my two output pins each running this table once like so

void loop(){
    sineWave(FET1); 
    sineWave(FET2);
}

where sineWave(int FET) would be the function to execute the table once. Clearly what I have is a long way from actual runable code, but I'm not afraid to try stuff. Ill post back if I can actually get this to run.

steinie44:
So you want to run a 60Hz pump at 240Hz?

Not specifically at 240Hz, but I have tested with my modified sine wave program up to 240 hz. It functions in a manner that appears to be normal. Every so often it bucks or rather makes a loud noise. Likely because it is a permanent magnet AC motor and really needs a smooth sine wave transition.

The noise/bucking happens it in the same intervals (albeit proportional to the frequency) as it would on lower frequencies which leads me to believe that driving it at 240Hz will work just fine provided I can get a clean sinusoidal signal to the motor.

240Hz sounds like bad news with an arduino, as how many steps in your synthesised sinewave would an arduino have time for?
I'm not saying never, but it does not seem too well matched to the hardware.

Is there anything along the lines of getting an external 40kHz pwm in, as that can 'buck' to use modest inductors to avoid heating which you'd want to try? If you end up with a reasonably efficient 12V to centre tapped transformer circuit and code, please can you post it as I'd want to use similar from a 328 chip which is about 15% busy looking at clock and mains grid timing. It can guarantee at least 6ms free in every 20ms but may be busy for up to 14ms in any 20ms interval.

What kind of motor is this pump? shaded-pole induction? universal?

MarkT:
What kind of motor is this pump? shaded-pole induction? universal?

Well I am assuming it is a permanent magnet AC motor. I know this sounds counter intuitive but the internal armature is a permanent magnet. The stater is a typical coil you would find in any universal motor. How this thing functions is you supply AC to the field coils and the magnet handles the rest. It spins exactly at the rate you alternate the signal. You find these motors in pond pumps a lot. Hardly any power output but really cheap to make and they can be submersed. since just the coils need to be sealed and using ceramic magnets works just fine.

My code for the Square wave is as follows. I have pre-programmed the delays in there and do no calculations.

As for the ability to drive something at 240Hz it might be very well that the bucking I was getting is the delay of the micro controller. I wish I understood more about the lower level stuff an binding the clock to the outputs with proper interrupt handling.

Anyways, both examples are designed to run the 60hz base to make sure I am doing things properly first. I wanted bare simple code before I started adding things like frequency adjusting and actual sine wave calculation/lookup. (Since these are square and modified sine the latter doesn't apply).

Square Wave Example:

#define MOSFET_N1 6
#define MOSFET_N2 7

void setup(){
  pinMode(MOSFET_N1, OUTPUT); // MOSFET 1
  pinMode(MOSFET_N2, OUTPUT);  // MOSFET 2  
}
 
void loop(){
  digitalWrite(MOSFET_N1, 1);
  delayMicroseconds(8333);
  digitalWrite(MOSFET_N1, 0);
  delayMicroseconds(26); 
  digitalWrite(MOSFET_N2, 1);
  delayMicroseconds(8333);
  digitalWrite(MOSFET_N2, 0);  
  delayMicroseconds(26);  
}

Bastardized Modified Sine Wave Example:

#define MOSFET_N1 5
#define MOSFET_N2 3

void setup(){
  pinMode(MOSFET_N1, OUTPUT); // MOSFET 1
  pinMode(MOSFET_N2, OUTPUT);  // MOSFET 2  
}
 
void loop(){
  delayMicroseconds(2083);
  digitalWrite(MOSFET_N1, 1);
  delayMicroseconds(4167);
  digitalWrite(MOSFET_N1, 0);
  delayMicroseconds(4167); // Two Half Delays
  digitalWrite(MOSFET_N2, 1);
  delayMicroseconds(4167);
  digitalWrite(MOSFET_N2, 0);  
  delayMicroseconds(2083);  
}

So I'm not entirely sure if this is what you are looking for but you could try using inline assembly code if you need to shorten the pulse durations.
http://playground.arduino.cc/Main/AVR

There are entire families of microprocessors specifically built to do this kind of real-time waveform synthesis.

None of the Arduino processors are related to those families, although the PWM hardware on the Arduinos is pretty formidable.

I suspect your basic "pond pump" motor is a shaded-pole motor and that will perform poorly once the frequency gets too far away from the design frequency. 3-phase induction motors are the usual basis of VFD systems.