VFD control with Arduino using RS485 link

Variable Frequency Drives (VFD) allow the control of spindles so speed can accurately be controlled and a detailed acceleration profile for the spindle and reverse rotation can all be handled. In essence a VFD is an three phase inverter for three-phase AC motor.

I am using a popular (I mean cheap) Chinese VFD and though the reference manual is not great, I could see there is a built-in RS-485 port. I usually control the start, stop and speed selection using the keyboard on the unit but I thought it will be more useful if I could control everything from the same Arduino is doing our CNC table control.

Some cheap RS-485 off eBay and some lines of code later, I can start, stop and change the speed from an Arduino. What a cool thing to have!




Some configuration of your VFD are needed before you can use it like that.  You need to set PD163=1 (I am using address 1 in the code). PD=164=1 (for setting serial to 9600bps) and PD165=0 (for using ASCII and 8N1 character format). On top of that, you need to set PD001=2 (for commands being provided through the communications port). 

Please note that doing that may interfere with your existing controls using external terminals, so be careful as that might make your emergency or external stop buttons to stop working. The built-in stop button still will stop the spindle but you need to power-cycle the VFD for accepting new start commands over the serial port.


Comments

Unknown said…
Hello. Management VDF through Arduino is very cool. I now also interested in such a task, but I have another inverter Delta VFD-M. I'm not good at programming, so I want to ask you for help. I have an Arduino Mega 2560. How to make them work together? Here is manual for my Delta VFD-M:
https://drive.google.com/file/d/0BxBSPbIgJc5LQ3VQQUR3dzVIUE0/view?usp=sharing

And Soft for pc:

https://drive.google.com/file/d/0BxBSPbIgJc5LNnlIWmV4UndpU2s/view?usp=sharing

Thank You!
misan said…
Hi,

What a difference: your VFD manual is actually written in English (not badly translated into English as mine) and it definitely can be done. My suggestion is for you to use ASCII mode.

While it is not complicated, it may take a few attempts to get it right and for that it is very handy to have the real device at hand.

The most challenging part is LRC calculation but the manual has it covered too.

You just have to set your serial to 9600 bps and send a string like this example ":010321020002D7" (please note this is not starting the VFD but reading a value).
Unknown said…
How about ASSCII mode? my VFD dosn't support 8,N,1 like in your programm ?
misan said…
Ok, you can just use 7N1 which is the default by doing
Serial.begin(9600, SERIAL_7N1 ); in setup()
Unknown said…
It's switching hardware (USB arduino) serial ? what about software serial(myserial) ?
Kunchala Anil said…
can you please explain the setSpeed(int v) function in the code.
misan said…
Have a look at footnote (7) in page 58 of the manual. It creates a string with the desired frequency value and sends it to the VFD.
Unknown said…
how must look ASCII 7N2 start motor message? for VFD-EL
i tryed to start motor and failed alot with your code in arduino uno...
01H: comunication adress
06H: write single register. mean write in memory to adress?
2000H: memory adress
10B: start motor, but why 10B what that mean?
how looks start command ? ":xx...xx" ????
someone told me to convert 2000H to DEC... i tryed but nothing happened.
misan said…
Hi Donatas,

What brand of VFD are you talking about?
misan said…
Hi Donatas,

What brand of VFD are you talking about?
Unknown said…
im using delta inverter VFD007E43T
misan said…
Have a look at this post http://anilarduino.blogspot.com.es/2015/05/controlling-vfd-with-arduino.html
Anonymous said…
Hi I am interested in controlling a 0.5 HP induction motor (7.9/7.2A and 115V). Its plugged into a wall socket (120VAC). What VFD would be suitable to control it using an Arduino MEGA ADK? Thank you!
misan said…
The motor depicted here is a 1 HP motor. You can use the same VFD I use (I think it is rated for 1.5KW or 2.2KW max) and the same code I created.
Anonymous said…
I think the VFD you used is for 220 VAC? I'm in Canada so would the VFD handle 120VAC 60HZ?

More information on the motor:
Model 5KH46JR15S
HP 0.5
RPM 1725/1140
Volts 115V
Cycle 60 Hz Cycle
Current 7.9A/7.2A
PF 85%
fab said…
hi miguel

is it possible to use marlin (arduino mega 2560+ramps) directly to start and stop the spindle. i have this model

http://www.prom-electric.ru/data/uploads/manuals/sunfar_e300_manual_en.pdf.pdf

(i think marlin-ramps-lcd is the perfect combination to have a controler without computer needed)
thanks
fabrice
DJ said…
Does this allow reversing the spindle as well? How?
misan said…
Yes it does.
Anonymous said…
Hello I was just wondering if you can read feedback from the drive unit, eg amps, speed, overload conditions

thanks
misan said…
Yes, it is possible (as far as your VFD offers that information). However the VFD I use does not seem to offer real time measurements of speed or amps over the serial comms (but it offers info on certain error conditions).
Mr. E said…
do you know if an AC Servo could be driven with VFD, perhaps reading 3 signals from hall sensors coupled to send the feedback to arduino ?
misan said…
I do not think so. It definitely is not ready to take any position feedback and it is aimed for speed control.
punk0 said…
Hi Miguel, thanks for your job, i want control many vfd's, from my arduino.
I want to find in your code, where you type the address of the vfd to add another address or addresses of other VFDs. I appreciate your help.
regards
Unknown said…
Hi Miguel,
I bought a 2.2kw Huanyang inverter but I seem to be having a lot of trouble getting it working. I cobbled up an Arduino based interface for my mill (does a lot more than sending commands to the VFD) but I can't seem to get this working. I can set the frequency (PD003) programmatically but I can't get it to start at all. I used your code as a baseline and mine is very similar, but I can't get it to start AND I don't seem to be getting any response back from the VFD (should I? manual is horrible). I send :01020303177070 to set it to 60Hz and that seems to work (I can set it to anything). Then I send it :01030101FA to start the thing (FWD) but nothing happens. Is there some magic setting that I'm missing?
misan said…
I cannot speak by Huanyang but I was getting responses from my commands. If you can set frequency that is a very good sign. Please note that system configuration is vital. I reckon PD001 has to be set to 3 ( to allow serial commands to start/stop the VFD ).
Unknown said…
I do get responses now. I changed the code to do a serial2.flush() before switching DE/RE and now I get responses but I still cannot read status and the motor never starts. When I send the frequency it gets echoed back exactly as I sent it. When I ask for frequency (:0104030000F8) I get no response at all. When I try to start it (:01030101FA) I get the response echoed but it does not start. Certainly PD001 is set to 3 and all the communication parameters are correct. What am I missing? The documentation is so poor I feel like I'm shooting in the dark. Is there some other setting or physical connection that has to be made (i.e. switch inputs)? The book is not clear. It shows function codes as 1: FUNC READ, 2: FUNC WRIT, 3: write control data, 4: read control status, 5: write inverter frequency data, 6&7: reserved, 8: loop test Then it shows a table which I assume is the control data we should write via function 3, but never explains it. It shows bit definitions from 7-0 as jogr|jogf\jog\r/f|stop|rev|for|run. I assume these are the basis for the forward/reverse/stop commands but I can't seem to get it to do anything. I can't say I understand r/f,rev,for,run. Are they exclusive or combined (as in set both for & run to make it go forward)? I sure hope you understand this thing...
Unknown said…
By the way, I have PD001 set to 2 (book says 0=operator, 1=external, 2=communication port). It only allows selections 0,1,or 2. When I send a new frequency it does show up in PD003 as it should. Too bad this this isn't really Modbus conformant. I would have expected a read/write register with the control bits but it looks like it has a function (code 3) to write some control bits with no way to read them back and a function (code 4) to read status bits but no actual registers. Am I correct?
misan said…
Is my sample code http://pastebin.com/QpmDDHsD not starting your motor? If so I would think there is a configuration problem (remember I do use address one).
Unknown said…
I found it. The book says PD002 is Source of Operating Frequency where 0=operator, 1=external terminals, 2-communication port, BUT the unit accepts the undocumented select of 3 (not listed in book). When PD002 is set to 3 it honors the motor forward/reverse/stops commands! I would never have even tried this except for your comment about setting PD001 to 3 (which you can't actually do). I still don't get a "bad" response (81 address returned) to a bad command but I'll work on that next.
Unknown said…
Wow is this a lousy manual. It says that it echoes back the command and sets the high bit of the address if it is rejected but that is not what it does. So far I have never seen the high bit set in any response. When you command it to run forward, reverse, or stop it does not echo the command. It replies with the status word which has a totally different layout and meaning. I suppose if I persist I will eventually figure this thing out but it is very irritating. It would have been easier to use this thing with the "external" interface (inputs for fwd, rev, stop, and voltage or current to set speed). I wonder if the RTU mode is as screwed up as this? Did you ever get far enough to actually do command/response with this thing?
misan said…
I paid not much attention to the responses, but they kind of made sense to me (as I remember I could use that for configuration backup). But it was long time since I had a look a this. I fact it seems I mentioned the right number but to the wrong variable. Glad that you find the right way to use that number 3 :-)
Unknown said…
Thank you, Miguel. I am still working on it when I can (I work a real job too). I'll post more as I figure things out. The magic "3" made a huge difference. I don't know how you ever figured that one out. My manual makes no mention of it at all.
misan said…
Serendipity :-)
PULSE - MANIA said…
Hi ,

A warm morning and merry Christmas. I am facing problem to interface my Delta VFD-M with Arduino. I am using RS232 to RS485 converter module to interface with the device. I tried a lot and googled with around all the libraries available.

Data sheet for the VFD can be downloaded from
http://www.delta.com.tw/product/em/drive/ac_motor/download/manual/VFD_M_EN_20100514.pdf

My efforts went in vain, please help me out with this issue.

My control requirements:

Control:
1. Frequency:
2. Start / Stop:
3. Forward / Reverse

Read:
1. 16 Registers data starting from 2000H

Email: dhrubajyoti2009@gmail.com
misan said…
Try with 4-64 page example in ASCII mode till you get the expected response, from there on it should be easy.
Hello Sir, I use RM5G VFD made in Taiwan invertor but on the manual of this invertor there is no information about PD163,PD164 and PD165,

The manual link is
here
Anonymous said…
Hi Miguel,
Thanks for all the content. But what do I need to send to the VfD for guest engine to run backwards? To start, ":01030101" will be sent to stop ":01030108", for 30Hz will ": 010203030BB837\r\n", but what does the code for "reverse " look like?

Many greetings, Michael
misan said…
this is what I use:
char* sp_start =":01030101"; // CW
char* sp_start_rev=":01030111"; // CCW
Anonymous said…
Thank you, that is what i needed.

Best regards,
Michael
Abdul Rafaeh said…
Hello
Can I please have the circuit diagram you used to connect arduino to a VFD. I am using an Arduino mega and a SD100-01D543 VFD.
Further this VFD also has a built in RS485, Do I need an external RS485 regardless ?
misan said…
I just connected the two RS-485 wires to the VFD. If your Mega unit has the built-in RS-485 interface all you need a two wires to the VFD.
Abdul Rafaeh said…
This comment has been removed by the author.
misan said…
Yes, you'll need to configure serial comms, address, etc. And operational modes too: accepting control from comms port.
Abdul Rafaeh said…
Can you please guide me? I am a having a hard time figuring it out?
Here is the manual of VFD that I am using
http://www.holip.com/upload/file/2017/09/133R0309%20HLP-SD100%20Series%20English%20Operating%20Manual%20V2017-01(20170828).pdf
Unknown said…
This comment has been removed by the author.
Unknown said…
Hi ,

A warm morning and merry Christmas. I am facing problem to interface my Delta VFD-E with Arduino. I am using RS232 to RS485 converter module to interface with the device. I tried a lot and googled with around all the libraries available.

Data sheet for the VFD-E can be downloaded from
https://www.google.com/url?sa=t&source=web&rct=j&url=http://www.delta.com.tw/product/em/drive/ac_motor/download/manual/VFD-EL_manual_en.pdf&ved=2ahUKEwiWnY_6177bAhWDcRQKHXPIDVUQFjABegQIBxAB&usg=AOvVaw1kb6dOEmX9CKTTs5oNvaEd
My efforts went in vain, please help me out with this issue.

My control requirements:

Control:
1. Frequency:
2. Start / Stop:
3. Forward / Reverse

Read:
1. 16 Registers data starting from 2000H

Email: samerhaleem2@gmail.com
Anonymous said…
Hello Mr. Sanchez,
first of all, could I have your email?
1. this is your code that you used, right? (https://pastebin.com/QpmDDHsD)
2. In which part did you enter the SERIAL_8N1?
3. How did you get these numbers? I mean these:
":010203030BB837\r\n" ----> for speed
":01040300" ----> for read_speed
":010203030BB8" ----> for change_speed
":01030108" ----> for stop
":01030101" ----> for start
I explain start's code and please check I'm right:
: -> 3AH
01 -> Address of vfd
03 -> write control data
01 -> I don't know
01 -> I don't know
4. what is the "V" in the "void setSpeed(int v)"?
5. Thanks a lot if you give a brief explanation about these codes:
n[9]=toHexa((v/256)>>4);
n[10]=toHexa((v/256)&0xf);
n[11]=toHexa((v&0xff)>>4);
n[12]=toHexa((v&0xff)&0xf);
thank you & best regards





Unknown said…
Hi sir. I wasn't really good in arduino and in this matter. Can you explain the code to me please? I have an ongoing project for motor control. It's my first time to encounter this programming setup. Please? God bless you. More power!
Nice! Your post was my inspiration for my project to build Arduino controller with a screen and an encoder to control FVD. I went further and used an Arduino library for modbus to communicate in RTU mode. Plus encoder to use as user input of desired RPM and another library for that. Turns out you have to use interrupts to read from encoder - proper library does that. RPM is calculated based on frequency (and gear ratio in my case) and displayed on OLED screen that is connected over I2C. And finally, last speed or frequency is stored in EEPROM, to remember the last settings after restart or power off.

Testing video: https://youtu.be/Ap4cbzAT04w (sorry, it is in Russian).
And the code: https://pastebin.com/UE3vDgUA

Very satisfied with result. And not without your help!
my VFD supports RTU Modbus and not ASCII, how to change the code according to RTU mode?
Unknown said…
proszę o schemat połączenia Arduino-GRBL z arduino-RS-485 i VFD-inverter


I am asking for the Arduino-GRBL connection diagram with arduino-RS-485 and VFD-inverter
Yaumil said…
Hi Sir
i wanna ask, my VFD didn't have the RS- and RS+ for the RS-485 cable, but they have A and B sockets for RS-485, is it okay to connect without knowing the + and - ? Thanks.
misan said…
Hi Yaumil,

Yes A/B or +/- are the same thing but there is not a common agreement https://en.wikipedia.org/wiki/RS-485

But, if you have a different VFD model/brand it is very likely my code will not work as it needs to be customized for each unit.
Yaumil said…
Hi Misan,

In general, what kind of variable needs to be change in order to make it work?

and when the RS-485 are connected to VFD, is it need to connect to the motor? just to tell if it really can control the VFD or not?

Kenny Ph said…
I am interested on this project. Can you please send me your wiring diagram? Heheh thanks
misan said…
I assumed it was obvious from the images, I guess it is not: RS-485 "A" goes to "RS+" on the VFD. "B" goes to "RS-".
Eklavya_Ravi said…
How to upload vfd code by Arduino
misan said…
It is linked in the blog post.

https://pastebin.com/QpmDDHsD
Few said…
Hi if set PD070=1(0-5v). Is 5v will get 50Hz? or 25Hz.
misan said…
@Few, I really have no idea. But I would assume 5v would give you the max frequency (being the highest voltage).
Stu said…
Hi,
If you are still around.
I'm trying to use your code but get the messages below when I "verify" the code.
I have tried a few things but am pretty new to Arduino. Any help would be much appreciated.
BTW I think you may have left out PD002=2 in your instructions, but as I haven't got it running yet I cant be sure.

C:\Users\user\Documents\Arduino\test.ino:13:18: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char* read_speed=":01040300";

^

C:\Users\user\Documents\Arduino\test.ino:14:20: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char* change_speed=":010203030BB8";

^

C:\Users\user\Documents\Arduino\test.ino:15:12: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char* stop=":01030108";

^

C:\Users\user\Documents\Arduino\test.ino:16:13: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

char* start=":01030101";
misan said…
These are just warnings, code is still most likely to work.
misan said…
https://www.youtube.com/watch?v=1NF8EFoPlrk also mentions PD002=2, I do not remember ATM but I reckon you are correct.
Stu said…
Yes it does upload to the Ardiuno and does run. So I thought everything was good until my RS 485 board arrived and I connected everything and it didn't work.
Maybe its something I have done, maybe its my RS485 board, I'm just using normal wire but over about 2m. I will try a few more things.

Thank you for your time.
Sebastián said…
Hi! About the wiring I don´t know much about RS485 protocol. My VFD-M says SG+ and SG- coming out from the RJ11 connector. And my RS485 adapter has A(D+) and B(D+). SG+ goes with A and SG- with B right?
misan said…
I think so Sebastián.
bala said…
Hi, i am using VFD007El21w with atmega2560, tried the below code with 7,N,2(Modbus,ASCII),7,E,1(Modbus,ASCII),7,O,1(Modbus,ASCII),7,N,1(Modbus,ASCII),7,E,1(Modbus,ASCII),7,O,1(Modbus,ASCII)
#include
// RS485 connections
// D8 = DI (TX)
// D9 = DE
// D10 = RE
// D11 = RO (RX)
#define VFD_START 1
#define VFD_STOP 2
#define VFD_SPEED 3

#define MAX_SIZE 20 // max size of data buffer

String speed=":010203030BB837\r\n";


char* read_speed=":01062001";
char* change_speed=":010203030BB8";
char* start=":010620000012C7\r\n";
char* stop=":010620000011C8\r\n";


SoftwareSerial myserial(11, 8); // RX, TX
void setup() {
Serial.begin(9600);
Serial1.begin(9600,SERIAL_7O2);
Serial.println("in setup");
// delay(100);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
digitalWrite(9, LOW); digitalWrite(10, LOW);
// delay(10);
query(start);

}//end of setup
void loop() {
}

void transmit(String msg) {
// activate driver
digitalWrite(9,HIGH); digitalWrite(9,HIGH);
delay(50);
Serial1.print(msg);
Serial1.flush();
//Serial1.print(start_vfd);
delay(1);
digitalWrite(9,LOW); digitalWrite(9,LOW);
Serial.print("msg");
Serial.println(msg);
}

char hexa(char byte) { // return hexa value of that ASCII char
if(byte<='9') return byte & 0x0f;
if(byte<='F') return (byte & 0x0f) + 9; // A=0x41 --> 0x0a
}

char toHexa(int i) {
if(i<10) return 0x30 | i;
return 0x41 + i - 10;
}

char crc(char* buffer) {
int l=strlen(buffer);
int i=1;
int chk=0;
while(i>4);
msg+=toHexa(lrc&0x0f);
msg+="\r\n";

transmit(msg);

}


Can you please help/guide me what is the mistage i am doing.
https://inverterdrive.com/file/DELTA-VFD-EL-W-User-Manual
misan said…
I am sorry but reviewing the manual and your code would take me a few hours of my time.

I did share my experience and code with the aim that it might be useful for other people.

I am sure the manufacturer of your VFD most likely can guide you, perhaps through some application engineer.

A lot of problems may have nothing to do with the code (as improper setup of the VFD).
fawad said…
I love your work,
recently i have been told to read data from VFD, using arduino MODBUS, is it possible to do that.
thank you
misan said…
Yes, it is possible to read some VFD data using MODBUS.
Unknown said…
Hi,
Is it possible to monitor the frequency of VFD motor using arduino? I am using ATV310 VFD which as RJ45 port. What change do i need to to as this VFD uses RTU mode communication.
Unknown said…
Hi,
I am using ATV310 VFD and i need to monitor the frequency in real time so i will be using a GSM module. This VFD is using RTU mode communication what change i need to in the code for communication between arduino and VFD.
misan said…
While Modbus is a standard, each manufacturer uses different ways, register names mean different things for each one, so there is not a simple answer to your question. RTU is simpler but uses a different CRC than ASCII comms.

Popular posts from this blog

How to get sinusoidal s-curve for a stepper motor

Stepper motor step signal timing calculation