Smartening Plantation Shutters

While @chris.huitema has been making amazing progress on his design, I was inspired and started working on mine again.

Like I mentioned in another post I started with a cheap and highly geared servo motor which worked really well. The pros of using a servo are that it has the potentiometer built in so no need for limit switches, percentage control is built in (move to 50%). Best of all - super cheap and super simple to assemble! For me, the cons are that it wasn’t easily back-drivable and still pretty noisy.

I dusted off the stepper motor idea again and retrofitted my servo design with a NEMA 11 which I quickly figured out simply wasn’t powerful enough to drive the shutters so I upgraded to a NEMA 14 35x35mm. Rather than use a potentiometer or limit switches, I opted to go for an AS5600 magnetic encoder which are really cheap, accurate, and generally seem to work well.

I super glued a tiny magnet to the rotor of the stepper motor and modeled a quick and dirty NEMA14/AS5600 adapter that sits on top. The magnetic encoder essentially turns the open stepper into a closed-loop stepper that it always knows where it is and how far it’s traveled, even if it loses power or is asleep to save power. I picked up some TMC2209 stepper motor drivers which are known for being super quiet and have been working on the physics piece and finally have a working (and ugly) prototype that uses the same style clip that the Chinese models use. In the video below I have it set to a loop to close to “0 degrees”, wait a few seconds, and then open to “210 degrees”. I manually move it a few times to show that even though it’s a stepper it always knows where it is and how far to open/close.

I think this covers all of my requirements and I love how quiet it is. The shutters are the noisiest part. I have a little more work to do in the mechanics department and then I’m going to switch my focus to the battery issue which I think is probably the last remaining challenge for me. I like the idea of having a single ESP32 per window that drives multiple motors, so I’m planning on designing a central battery charging/LoRa circuit and then running wires to the 2-4 motors per window that I have.

One blocker is that the AS5600 is locked into a single I2C address which means I’ll need to find something similar with adjustable addresses or find some other workaround. I also am thinking of adding a tactile button that will initiate a one-time at-installation “homing” routine to automatically set and save the limits of the window and adjust the offset so that it knows the full range of motion.

Once I get the last remaining kinks worked out of the mechanics I can share the STL files if anyone’s interested.

4 Likes

Wow that Nema 14 stepper is silent!.. that is the winner.

Sorry for the delays between posts… been on holidays and still fighting printer problems

A firmware update on the Mage and the latest version of the slicer software from Creality seems to have resolved many of the issues, it’s still really slow but the prints are better and the artifacts that looked like a failing lcd have been resolved.




And this is it all assembled with the cover


BUT it’s a dud… unfortunately the corner warped in the one place that has an effect!


So basically the lower pin that takes 90% of the force from the drive mechanism is printed on an angle because of the warping, this means the pin doesn’t sit in the groove of the actuator which is straight. The gears just push 8t off.

I started a new print as I pulled this one off the printer before I noticed the issue. Fingers crossed it prints ok, but I’m guessing it will be the same. On the weekend I’ll fix up the support in that area and get it working properly

I got some new motors, 3v 15rpm that seem to be pretty quiet compared to the other ones I used. I also printed a cover for the gearbox to try dampen the noise too. The true test will be when it’s working properly and loaded up… only a few days now

1 Like

Yep as I thought the same result printing again without changing anything!

Before even pulling it off the build plate I can see the supports aren’t attached and there is warping. Also the cover needs some extra help to stay round.

Only other change I’m going to make is to the shadow line of one edge the cover… somehow I missed it completely and can see a slight gap when looking at it from side on.

Edit: Im still actively working on this - yet another week has passed, over 90hours of printing and not a single one has worked! it doesn’t seem to matter how much support there is, it just keeps ripping off, its actually so violent that the whole machine twists up as it rips the plate up, it starts so fast it creates a sonic boom, but slows down so much you can barely see it moving. they seem to have the acceleration going in the wrong direction, and there is only 3 speed settings, none of which work. Ive had to texture the build plate, change to the super heavy duty supports at about 75% density and 45 degree support. there is something fundamentally wrong with the speed settings on the machine.

So its been a while… I’ve had a chance to try out the Heltec LoRa module. Initially i wasted a solid week trying to use the Heltec library and board definitions etc. I gave up on that and found a library that works well, i can setup the radio and put the device to deep sleep and then successful waking up from LoRa parsing the packet that woke it up. Interestingly the RTC time seems to carry through the deep sleep too. so this should make things easier. SX126x-Arduino Library

Not wanting to go a full LoraWAN setup I have been trying to conceive a way to communicate to a base station securely. Given these radios have a significant transmission distance there is a chance someone could capture the packets and replay them, or decode them and start messing with the blinds. I also wanted to keep it super light weight in the amount of data going back and forward, as once there is dozens of these things around my house it may start getting a little congested. another reason is for trying to keep the device sleeping as long as possible to increase battery life, hopefully smaller packets and simple checking of first byte to decide if it goes back to sleep or stays awake will help

My idea is to use AES encryption for most of the packet, this will stop someone decoding but wont stop the replay attacks, for those I’ve chosen to use a one time password, like a TOTP 6 digit code you get from authenticator that’s included in the encrypted part of the packet. So the idea is to setup the radio and put the device to sleep. when the device receives a packet it will wake up, the first byte will be the address the packet is for - if this doesn’t match it will go back to sleep, otherwise it will read byte 2, which will be the decrypted packet size, it will then decrypt the remainder of the packet. this will include the OTP which it will verify using its RTC. if it passes then it will perform the command received. if it fails the OTP checks it will perform some verification of its own RTC and sync time with the server/base unit. every packet should be completely different from the next one because its effected by the RTC time or random number then encrypted (apart from the first byte or two) and replaying the same packet wont work unless its within a few seconds, which wont effect anything.

LoRa packet setup
01: Address:  0x00 = base, 0x01 thru 0xfe devices, 0xff broadcast to all
02: decrypted size: size of decrypted data. len in decrypt to cleartext
packet encrypted from here to end. use size above and stored key/IV to decode below part of message.
03-08: otp verification bytes
09: from address: to confirm its from base unit or which device to reply.
10: command
11-XX: payload

commands and payloads


direction			Command			Payload
device to base		time request	rtc time or if RTC not set generate random number. 10sec timeout. rate limit 
base to device		time sync		epoch time now. used to set RTC. RTC should hold in deep sleep. rate limit 
base to device		status request	blind # (0xff for system status)
device to base		blind status	blind #, state, position
device to base		system status	battery, uptime, awake/sleep ratio, total blinds #, blind #, state, position, repeat for each blind
base to device		blind command	blind # (0xff for all), command (open, close, stop or position)
base to device		parameter set	blind # (0xff for all), parameter, value
															zero limit, na (manually set blind to fully closed, this command sets position sensor value for the position)
															open limit, na (manually set blind to fully open, this command sets position sensor value for the position)
															Motor open speed, dutycycle (set motor speed/power)
															Motor close speed, dutycycle (set motor speed/power)
															PWM, freq (set motor PWM)
															Open time, time in ms (time blind is expected to take to fully open - used for timeout)
															Close time, time in ms (time blind is expected to take to fully close - used for timeout)
															Disengage time, time in ms (backdrive time required to set drive back to neutral position)															
base to device		wifiAP enable		true/false

and the time sync/OTP

otp verification notes: to prevent replay attacks	
different hmac for send and receive. base encodes with key1, and decodes with key2. device encodes key2 and decodes key 1
use 1sec steps, allow codes for +/- 5 values. this limits replay attacks to 5sec
if out of sync by more than 3 value (3sec) perform time sync of device - device side limit to 1x per min. calibrate rtc if needed. if wake every 10min then it shouldn't drift much
if otp verification failed,
	base side:  	if RTC is set - only allow time request command, number in request to generate the otp for the reply time sync command to device.
					if RTC is not set - set RTC to server time, repeat verification
					if RTC requres adjustement perform a time sync command using old time to set new time on devices. 

	device side: 	if RTC is not set then its expected - 
						time request with random generated number between 1000 and 300000. wait upto 10sec for reply, then repeat with new random number upto 3 times. 
						base reply - check random number is valid and use to generate otp for response - will only be valid this request with 10sec timeout.
					if RTC is set then possible replay attack - 
						perform time request with current device rtc, set payload as current rtc. 
						base reply - if request otp is valid, reply with current epoch time (ie your rtc ok, but likely received a replay, or a replay of time request was sent to server, would fail below). 
									 if otp fails - device time is wrong, use device rtc to generate otp and reply with new time.

I know this isn’t how its normally done, to have AES key and IV stored on the device and on the server and using TOTP like this to block replay attacks… i just find another way to do it with ready made libraries designed for radio transmission.

I’m thinking LoRa for all the main control and using the ESP32 wifi AP to setup the device. Basically on device boot if the device isnt setup or keys etc aren’t set, or if the ‘user’ button pressed or the WiFi enable command received via LoRa… then turn on the AP, and have a simple webpage.

wifi settings: 	LoRa settings(LoRa settings, AES key/IV, OTP HMAC keys send/receive)
				number of blind columns
				number of blind rows
				perform i2c scan
				set order of i2c addresses - test button to function a blind.
				per blind setting/status
					rw local/i2c
					rw i2c address if applicable
					ro current position
					ro current real position
					rw current ewma alpha - exponential moving average filter alpha value
					ro current state
					rw engaged state
					rw zero value
					rw max value
					rw open speed
					rw close speed
					rw pwm frequency
					rw open time limit
					rw close time limit
					rw disengage time

And then… all the slave devices will need i2c… ive hashed out the below functions. idea is to use a cheap ESP32-C3 supermini in the slave devices, and if the runs of i2c are a bit long i will include a CJMCU-9515 i2c repeater. power will be from the battery of the main actuator, so only 4 wires daisy chaining the slaves.

i2c commands
get position - read current filtered mapped position
get real position - read current filtered non mapped position
get state - returns open, closed, opening, closing
get engaged - returns true if motor is engaged, or false when disenaged. assumed based on back off time.
get zero limit - get current position as map 0
get open limit - get current position as map 100
get open speed
get close speed
get pwm frequency
get open time limit
get close time limit
get disengage time
get voltage - read voltage at esp 5v input - will need a voltage divider setup to do this. useful for determining voltage drop when motors are running.

set zero limit - set current position as map 0
set open limit - set current position as map 100
set sleep - puts esp and motor driver to sleep.
set position - make it move to position
set disengage - perform disengage routine to try unlocking motor
set open speed
set close speed
set pwm frequency
set open time limit
set close time limit
set disengage time

So the Heltec Wifi stick lite V3 has a MOSFET to connect the battery to a voltage divider for measuring battery voltage without constantly draining the battery, controlled by ADCctl/GPIO37. My thoughts are this MOSFET is rated for a few amps and the trace to it looks beefy, so i will use that over the Vext. The Vext will enable an output supplying 3v3. my thoughts are that there will be some voltage drop on the slaves that are further away, and hopefully the extra voltage will help. it may make the motor speed a bit variable so will need some testing. the output of the MOSFET is a tiny trace with a voltage divider, but soldering directly on the output pin of the MOSFET should do the trick.

My thoughts for the way the device will work, on receiving a command for status or moving the blinds

Set ADCctl GPIO37 low, powers up slave devices
wait for bootup time to pass
scan i2c devices. 
read status of each blind (if available in scan)
send sleep command to not required slaves/actuators
send command to required actuator/s
read update periodically
once position achieved or timed out put actuator to sleep.
read battery voltage. 
	all actuators should be in sleep mode to get accurate reading. 
	read voltage during moves to see how much it pulls down. 
	possibly setup voltage divider at esp32 supermini. perhaps bypass shotkey for extra 0.5v

For the base station, i would like to take the command/payload from the decoded LoRa message and transmit via MQTT to HA, and subscribe to topics, and encode them to send to the relevant device. then setup MQTT covers for each blind in HA to be able to control them.

I would like to think this is a great starting point for many battery powered devices, not just these blinds. there are loads of lora sensors that live life sleeping, but i cant see any do-ers, things that can wake up and perform an action.
I’ve been watching this thread, ESPlanty and thinking it would be another good use for it, allowing more range and be able to wake it up remotely to provide additional water if the weather is going to be higher than normal.
I’m also thinking of my cheap outdoor water misting system, it has a timer built in… but i would rather only have it trigger when there is someone in an area and the temperature is above a certain temp, both of which i can get from HA easily… its just finding a battery device that listens and is fairly secure. my old RF switchboard gets randomly activated and deactivated by a neighbor…

Unfortunately I’ve forgotten more than i can remember with C++ and Arduino… and while i can fumble my way through some things i find myself banging my head a against a wall constantly fighting with strings and pointers and all that good stuff. Does anyone want to take on a challenge and help me build this one out?

update1:
program written that handles sleeping/wakeup, and the lora TX/RX including the AES and OTP used as an IV. Time sync is implemented so the device can sync with the master. response time is insane! only 100ms to wake, receive and decrypt the message
next up is parsing the command and payload and doing stuff with it, followed by MQTT on the master

update2:
have had a few devices reporting battery level back to the gateway, and the gateway publishing MQTT to HA for logging, with 60second update intervals the 1100mah battery is dropping by about 0.1v per day. so roughly a week to 10 days battery life without motor movements. these devices are asleep 98.6% of the time! (but i don’t expect to do 60sec updates on the blinds normally)

I’ve got 1 actuator that’s receiving a move command every 30sec and moving for 5.5seconds each time (no load) this is dropping the 2000mh battery by 0.25v per day. this equates to 20% awake time on the device, most of which is motor moving time. well above normal usage.

response time from the command to motor moving is unmeasurable… in the milliseconds. i normally hear the motor start while the text comes in on the terminal from the gateway sending the message. I’ve made a few optimization’s and have the wakeup down to 25ms for a message not directed to that device, and about 80ms to parse the full packet, perform the decryption, verify the OTP, parse the command and trigger the action. I’m also seeing time variations of +/- 2 seconds per day on the RTC used for OTP… so it looks stable enough and shouldn’t be continuously syncing. will be interesting to see how it goes when they get hot in a window.

I tried some small solar panel 110mm x 60mm, but it only charged when in direct sunlight, I’m going to try a few in parallel to see if that helps. but given the low power usage I’m observing so far it shouldn’t take much to to it up each day.

still a load of work to be done, the code is a shambles at the moment but slowly night by night i’m getting more things done. currently im working on the the motor/position control of the actuator and parsing the blind control command, then ill get the MQTT subscriptions on the gateway worked out so i can control via home assistant.

I put together one of the slave devices, with the esp32-c3 and a motor controller, but I’m realizing that i will need a custom PCB to mount the modules to, its very time consuming soldering so many wires, and they are fragile… im also thinking for connectors for the slaves… will be much better to have them on a PCB. maybe when i need a break from programming.

2 Likes

Another project I found

https://diyodemag.com/projects/automating_plantation_shutter_controller_psc_esp8266_esp32

https://diyodemag.com/projects/automating_plantation_shutter_controller_psc_esp8266_esp32_part_2

Thanks for the links, I’m going to be cut and pasting many sections of his code! we have very similar ideas, and have encountered the same problems.

as mentioned in the update 2 of the post above, I’m making really good progress with the Lora module and low power consumption, in a way its very similar to the 433mhz module he is using, i just added encryption and a command/payload structure so all the controls and feedback are performed via lora. I’m now working on implementing Arduino bootstrapper on the gateway module, the bootstrapper will handle the mqtt side of things, the HA auto discovery etc and convert the mqtt commands into the encrypted lora packets to the relevant device. and take the packets from the device and publish to mqtt. later on I may setup an AP on the device to set the AES and HMAC keys and to set the Gateway address, perhaps some of the LoRa settings… but for now i think hard coded is ok.

the actuator device can spend most of the time with the esp32 asleep and the radio in low power listen mode to save power, so hopefully the solar panel can be quite small, and not too intrusive. the 10w panel he uses doesn’t comply with WAF guidelines, I hope to get away with 2 small 110mm x 60mm panels to power 12 sections of shutters, initial testing is good for the devices that have direct sunlight, but I’m yet to find a solution for the devices that are always in the shade. I will give some energy harvester modules a go and see if they can provide enough to trickle charge with the small panels, i think 3 or 4 small panels across the top or bottom of the window will be pretty un-noticeable.

I realize this in the hardware section, and nothing but respect for those trying to make their own devices, however I have settled on trying to make this one work. It supports RF and BLE at the same time. BLE is tuya but since this is not a WiFi device, Tuya is only needed to get the encryption secret. Yes it expires and will have to be renewed but maybe later I will try to do the equivalent of a Man In The Middle attack on it and find a way to spoof it. There is a promising repo for Tuya bluetooth control. RF will never be able to report position but BLE does.

https://electric.garden/guangdong-a-oktechnology-grand-developmentco-2avvd/plantation-shutter-motor-am20d50n

Here are internal photos of the AM20 device.
https://electric.garden/guangdong-a-oktechnology-grand-developmentco-2avvd/photos/AM20D50N-Internal-Photos-Guangdong-A-OKTECHNOLOGY-GRAND-DEVELOPMENTCO-2avvdam20d50n-ex-1-4.pdf

Thanks for the teardown photos, always useful for ideas!

It would definitely be easier to use something off the shelf, but it doesn’t meet my needs as mentioned above. I think I’ve spent more hours on this project than a lifetime of manually opening and closing the blinds, but I’m enjoying it and hopefully soon ill be able to share the files so others can make their own too.

while not really teardown photo’s… here are the latest teaser/progress photos from my build

yep… i couldn’t handle how fragile all the wires were and how long they take to assemble, so i made a PCB… and I’m so impatient i did it at home so i didn’t have to wait a couple of weeks to get it! i tried out the positive photo resist on the resin 3d printer idea and it worked a treat. its quick and dirty with no ground plane or anything, but just the bare minimum. all done in 2 days from starting the design.



I went for simple single sided PCB, and thru hole components for easy DIY assembly, and the 2.5mm pitch JST connectors so its simple enough to crimp at home for making the cables to the slave boards. Still needs some minor tweaks before I send off to get a couple of dozen made at a fab house.

I’m going to make some slave boards too with the ESP32-C3 instead of the heltec, they will have i2c repeaters built in and will be daisy chainable. Here is the prototype hand wired version. I plan on doing some testing over the weekend to make sure the pins i have chosen on the c3 work as expected

Notice the boost module on the main board, it steps the 3.7v up to 5v. I’ve found running the n20 from 5v increases the torque from just enough to more than enough, it can also be tweaked up to 8v or 9 v if really needed. I also run the 5v to the i2c sockets, so the slaves will have a 5v supply, if running the 8 or 9v it will need to be dropped down for the c3… ill figure that out later when the need arises… @merlinn31 will be happy to note the 4pin header for the motor… so it will support a stepper too!

There will be a couple of small tweaks to the 3d print files too, I’ve decided to print them directly on the build plate in a vertical direction and although the print time will be 3 times as long i should be able to print a dozen at a time, and the cover will slide on from one end rather than clipping on like the version shown above. this will minimize the support material too. I need to make a little more access room for connecting the i2c ports and a little bit more room for the cable entry for the slaves. still having tolerance issues with the new printer, but will hopefully get it dialed in over the next few prints

Still making slow progress with the software, the device is now accepting open/close/position/stop commands and reporting state, position and battery level, although its all hard coded settings at the moment for keys and filters etc… the gateway is sending those status via MQTT, but I’ve still got to figure out how to subscribe to topics and act on them, currently it just sends a random position every couple of minutes. I’m going to study the ratgdo mqtt code in detail and see if i can make that work for me, although i want to make it very dynamic so when you add a actuator with the right keys it will just magically send a discovery packet to HA and subscribe to the topics etc.

1 Like

@chris.huitema Wow! That is amazing! Nice progress!

Have you looked into support via ESPHOME over MQTT discovery?

I was an early adopter of RATGDO (v1.0) and I added HA discovery via MQTT before it was even supported.

Since then I have upgraded the RATGDO hardware, and now use/prefer the ESPHome interface. (OTA updates, ability to view logs, etc)

That was exactly the starting point I was planning on using… I saw the way it was done and it’s very neat

I just haven’t figured out how to make it dynamic so when a new device connects it generates the discovery messages based on the device id

Any more revisions?

2 Likes

Any updates on this project as well, @merlinn31?

Following both solutions closely… planning on tackling one of these projects for my own shutters!

1 Like

Just checking in to see where all these projects are at. Are any viable (purchasable) at this point?

We’re renovating our master bath and have a bay window (3 windows) that my wife wants shutters on. Right now I’m somewhere between the Alibaba Tuya motors ($50 each but from the reviews not amazing) and the Norman shutters ($4k for all 3 windows including the shutters and motors). At this point I’d do the Norman… if only they integrated with HA. A sad state of affairs, and I agree with those doing the projects above that there is definitely a market of rich homeowners with these shutters who would pay for viable smart motors.

I’m still working on mine when I get time, unfortunately work has been very busy over the last few months. Hopefully over the next couple of weeks I’ll have a first release of software for testing. I have had half a dozen working for the last month but need to make them dynamic as it’s a pain in the bum adding additional ones and manually configure them each time

The hardware design is pretty much done, it is in a good working state but I want to refine the cover a bit more and make it easier and quicker to print.

I’m also close to finalizing the PCB and doing an order of 50 from pcbway … the handmade ones I made worked well, so it’s just ground planes and silkscreen stuff…

2 Likes

I have been watching this great thread for a few months. Have there been any further developments?

I have 20+ shutters begging to be made smart. Thank you to everyone for sharing these projects!

Would love to see the STLs if you’re willing to share.

1 Like