Variable Frequency Drive over Wifi

TLDR: Set the waterpump’s power over wifi

I’m using a Siemens Micromaster Vector to continuously drive a waterpump. This way, i can change the frequency and with this the power usage.

Unfortunately, the inverter is placed in a wet hole together with the pump and i don’t want to climb down to change the frequency. So i want this device in my network.

I used the ESP8266 on an ESP-01 board with the Mcunode software. The first one is a wifi-to-serial bridge and available for 3$. The software provides an arduino-like interpreter called ‘Lua’ which makes it possible to change the configuration on the fly and also to add new features without setting up the whole toolchain.

top of the adapter board

top of the adapter board

The Inverter provides one 250mA, 5V output to drive RS485 adaptors. The ESP8266 uses 300mA and up to 500mA in peaks. To make this work, I’ve used a cheap integrated buck converter module for 5o Cent. They are called KIS-3R33s, can take up to 26V input voltage and put out 3A of current. At 90% efficiency this comes out to 5V * 250mA = 0.9 * (3,3V * I) -> I = 341mA. I mounted the converter on top of the Wifi module to save some space.

bottom of adaptor board

bottom of adaptor board

Here you an see my usual mis usage of solder to create traces. The red wire on top pulls CH_PD to Vcc. GPIO0 and GPIO2 are used, RX and TX are free.

Because i had no RS485 adaptor boards to interface the serial link on the Inverter i had to compromise. I used one pin to generate a PWM at 1kHz. This signal is low passed through a RC filter (R = 8kΩ, C~4µF) to generate an analog voltage in the range of [oV, 3,3V].

This voltage is fed into the analog control on the inverter which expects a voltage in the range of [0V, 10V]. To circumvent the level shifting problem i configured the inverter to put out up to 210Hz. As I’m only using 1/3 of this range, i can set up to 210HZ / 3 = 370Hz which is enough for me. The disadvantage is that I’m loosing some resolution.

Figure 2.2.4: Control Connections - MICROMASTER Vector

Figure 2.2.4: Control Connections – MICROMASTER Vector

I followed the manual for the analog connections. I connected pin 6 to ping 9 which enables auto start and turning counter clockwise. Pin 4(AIN-) has to be connected to 0V on pin2. The analog signal from the RC filter is connected to pin 3 (AIN+).

The power is taken from pin 26 (P5V+) and from pin 2 (0V). I didn’t abuse pin 23 (PE) as Ground.

The pwm.lua script is simple.

pwm.setup(4,1000,512)
pwm.start(4)

Which just sets up the pump at a default frequency of 70Hz / 2 = 35Hz.

This script is called from my lua.init file:

-- run telnet server
dofile("telnet.lua")
dofile("wifi.lua")
dofile("temperature.lua")

Here you can also see my remote interface which is just the default telnet server example in telnet.lua:

-- a simple telnet server
s=net.createServer(net.TCP,180) 
s:listen(23,function(c) 
function s_output(str) 
  if(c~=nil) 
     then c:send(str)
  end 
end 
node.output(s_output, 0)   -- re-direct output to function s_ouput.

c:on("receive",function(c,l) 
  node.input(l)           -- works like pcall(loadstring(l)) but support multiple separate line
end) 
c:on("disconnection",function(c) 
  node.output(nil)        -- un-regist the redirect output function, output goes to serial
end) 
--print("Welcome to the telnet server on esp8266")
end)

the wifi.lua holds my passwords and some startup information for the user.

As i still had one pin left i decided to connect a DS18B20 sensor to measure the outside temperature. telnet.lua:

pin = 3
ow.setup(pin)
count = 0

addr = ow.reset_search(pin)
repeat
count = count + 1
tmr.wdclr()

if (addr == nil) then
-- print("No more addresses.")
else
-- print("Address: ")
-- print(addr:byte(1,8))
crc = ow.crc8(string.sub(addr,1,7))
if (crc == addr:byte(8)) then
if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
--  print("Device is a DS18S20 family device.")
      ow.reset(pin)
      ow.select(pin, addr)
      ow.write(pin, 0x44, 1)
      tmr.delay(1000000)
      present = ow.reset(pin)
      ow.select(pin, addr)
      ow.write(pin,0xBE, 1)
--      print("Present = "..present) 
      data = nil
      data = string.char(ow.read(pin))
      for i = 1, 8 do
        data = data .. string.char(ow.read(pin))
      end
--      print(data:byte(1,9))
      crc = ow.crc8(string.sub(data,1,8))
--      print("CRC="..crc)
      if (crc == data:byte(9)) then
         t = (data:byte(1) + data:byte(2) * 256) * 625
         t1 = t / 10000
         t2 = t % 10000
         print("Temperature= "..t1.."."..t2.." Centigrade")
      else
         print("Wrong CRC!!!")
      end                   
      tmr.wdclr()
else
  print("Device family is not recognized.")
end
else
print("CRC is not valid!")
end
end
addr = ow.search(pin)
until(addr == nil)

This is a less verbose version of the default script. Onewire actually worked flawlessly from the start.

If I would do it again, i would use the esp8266-transparent-bridge project from github and a RS485 converter. And i would use more capacitance for the RC filter. The target frequency changes continuously. I didn’t expect the inverter’s ADC to be that fast. The actual frequency changes really slow, so it is not a real problem, just ugly.