Fighting with computers

Computers are not always friendly.

Friday, October 10, 2014

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.


  • At 11:12 pm, Blogger xodes1 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:

    And Soft for pc:

    Thank You!

  • At 12:25 am, Blogger Miguel Sánchez said…


    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).

  • At 1:01 am, Blogger xodes1 said…

    How about ASSCII mode? my VFD dosn't support 8,N,1 like in your programm ?

  • At 8:08 am, Blogger Miguel Sánchez said…

    Ok, you can just use 7N1 which is the default by doing
    Serial.begin(9600, SERIAL_7N1 ); in setup()

  • At 1:06 pm, Blogger xodes1 said…

    It's switching hardware (USB arduino) serial ? what about software serial(myserial) ?

  • At 6:16 am, Blogger anil kunchala said…

    can you please explain the setSpeed(int v) function in the code.

  • At 8:55 am, Blogger Miguel Sánchez 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.

  • At 1:05 pm, Blogger Donatas Akutis 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.

  • At 1:09 pm, Blogger Miguel Sánchez said…

    Hi Donatas,

    What brand of VFD are you talking about?

  • At 1:09 pm, Blogger Miguel Sánchez said…

    Hi Donatas,

    What brand of VFD are you talking about?

  • At 1:10 pm, Blogger Donatas Akutis said…

    im using delta inverter VFD007E43T

  • At 1:12 pm, Blogger Miguel Sánchez said…

    Have a look at this post

  • At 3:26 pm, Anonymous 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!

  • At 3:32 pm, Blogger Miguel Sánchez 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.

  • At 3:46 pm, Anonymous 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%

  • At 3:46 am, Blogger Fabrice fabrap said…

    hi miguel

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

    (i think marlin-ramps-lcd is the perfect combination to have a controler without computer needed)

  • At 5:08 am, Blogger DJ said…

    Does this allow reversing the spindle as well? How?

  • At 8:32 am, Blogger Miguel Sánchez said…

    Yes it does.

  • At 12:48 pm, Anonymous Anonymous said…

    Hello I was just wondering if you can read feedback from the drive unit, eg amps, speed, overload conditions


  • At 12:54 pm, Blogger Miguel Sánchez 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).

  • At 11:37 pm, Blogger 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 ?

  • At 10:01 am, Blogger Miguel Sánchez said…

    I do not think so. It definitely is not ready to take any position feedback and it is aimed for speed control.

  • At 12:19 am, Blogger 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.

  • At 8:01 pm, Blogger Robert Bain 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?

  • At 10:45 pm, Blogger Miguel Sánchez 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 ).

  • At 4:12 pm, Blogger Robert Bain 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...

  • At 4:27 pm, Blogger Robert Bain 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?

  • At 4:33 pm, Blogger Miguel Sánchez said…

    Is my sample code not starting your motor? If so I would think there is a configuration problem (remember I do use address one).

  • At 4:42 pm, Blogger Robert Bain 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.

  • At 5:47 pm, Blogger Robert Bain 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?

  • At 8:44 pm, Blogger Miguel Sánchez 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 :-)

  • At 5:11 am, Blogger Robert Bain 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.

  • At 9:05 am, Blogger Miguel Sánchez said…

    Serendipity :-)

  • At 12:36 pm, Blogger 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

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

    My control requirements:

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

    1. 16 Registers data starting from 2000H


  • At 1:28 pm, Blogger Miguel Sánchez said…

    Try with 4-64 page example in ASCII mode till you get the expected response, from there on it should be easy.


Post a Comment

<< Home