Arduino for unusual serial protocols? - Page 1
Forum section: electronics / projects

author: compet17
author_rank: Regular Contributor
timestamp: June 26, 2018, 03:41:22 pm
content: We have a problem with our automatic sun shade control unit.... I think we need a new one but because it's an old product, there is nothin on the market to replace it. Of course we could replace the entire system - all 100 motor control units, wiring etc. that costs a fortune!My idea is to program an Arduino or something similar to send the commands to the motor units.The protocol is relatively simple: There are 8 zones (A-H) of which only 4 are used in this building and each zone can be given a command for UP, DOWN or CLOSE the shades.Each 30 bit data block is transmitted twice: 57ms data, 32ms pause, 57ms data... then 59ms pause... and again 57/32/57ms with a second data block (execute command).So the complete pattern looks like this: (57ms-command/32ms-pause/57ms-command...59ms-pause...57ms-execute/32ms-pause/57ms-execute)The question is: Is there an Arduino library that lets you create such custom serial data patterns? I mean I could also write code to turn an I/O port on and off in that manner but I'm pretty sure someone else has already done this for me :-)Or maybe someone has a better idea? But please no PC or laptop solution, it must be small and fit into the building cable duct.

author: Nusa
author_rank: Super Contributor
timestamp: June 26, 2018, 07:39:24 pm
content: Depends. Do you actually have the protocol, or are the 30 bits just captured data?57ms for 30 bits would be about 550 baud (in my head ballpark calculation...do the math yourself to be sure).If the 30 bits are 3 8-bit characters with 1 start and 1 stop bit per character, and you know what those 3-character combinations are, then you should have no problem using libraries.

author: rstofer
author_rank: Super Contributor
timestamp: June 26, 2018, 08:44:20 pm
content: There are 1,670,000 hits on Google for 'arduino sun shade control'I don't know that any of them have anything to do with your system and you didn't provide that information.Unless you can find a matching project, I doubt that somebody is going to hand you a functioning library. You can look at some of the IR projects to see how to generate timing.https://learn.sparkfun.com/tutorials/ir-communication

author: compet17
author_rank: Regular Contributor
timestamp: June 27, 2018, 07:45:36 am
content: I think that IR signaling stuff could really help. In fact the signals I captured with the scope look very similar. Thanks for leading me in this direction... that's a new point of view.The problem with our system is that it was developed in a time when no standards existed and many manufacturers made their own protocols. I would be a huge coincidence if someone has already made something for our system. But I will take a look into that...If you refine your search with "Griesser" and/or "Multronic" (manufacturer/system name) then you will find 0 results.

author: compet17
author_rank: Regular Contributor
timestamp: June 27, 2018, 07:55:14 am
content: or I do simply switch one output on and off for the desired times. There are only 16 30bit commands that must be generated. These could be stored inside the script and recalled when needed...

author: Doctorandus_P
author_rank: Super Contributor
timestamp: June 27, 2018, 08:24:16 am
content: It is probably (very likely) a simple protocol, where each bit or group of bits is mapped to some function, and 30 bits is not much.Probaby pretty easy to reverse engineer.Start by capturing a lot of data and look at the bits that change in the data stream.How many bits change between function "up" and function "down"...How do you capture the data? Do you look at it with an oscilloscope?Try it with a cheap logic analyser from Ali / Ebay / China / etc. Search for "24m 8ch" and use it with Sigrok / Pulseview.It is also likely that there is a checksum somewhere in the data stream. Usually at the end of a packet.Also note that everwhere that long wires are involved you have to think carefully about fault conditions, accidental connection to external voltages, ESD and more to make your circuit reliable and last long.Writing the software for such a simple protocol is probably easier than trying to find it on internet.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: June 27, 2018, 08:31:10 am
content: Let's get physical!What is the underlying protocol? RS232,RS485,one wire, two wire...What are the voltage levels?Any microcontroller should do what you want but if you can be a bit more specific we could probably suggest something closer to your requirement.FWIW ESP32 sounds quite interesting and it would allow me to connect remotely and hack your sunshades

author: hamster_nz
author_rank: Super Contributor
timestamp: June 27, 2018, 08:46:26 am
content: +1 for the ESP32. It has a 'RMT' perpherial that is designed for playing back bit streams like IR remotes or smart LEDs or sensors.Perfect if you enjoy low-level coding with the ESP-IDF 'C' environment.... The Arduino library support might not yet utilize it.

author: compet17
author_rank: Regular Contributor
timestamp: June 28, 2018, 10:21:36 am
content: I made some progress and it actually worksHere are some details in case someone is interested....As I said before there are 8 possible groups of shade controllers each can be told to go UP, DOWN and CLOSE but I only need 4 of them. So I took my old and trusty LeCroy digital scope and captured each individual command.It's a two wire bus interface with 0 and 24V levels while a short impulse means 0 and a long impulse means 1. Speed is about 2ms from rising edge to rising edge. Funny part is that each bit is transmitted twice (like: 001100001100000000...) and the full command is also sent twice.Maybe to make sure that everything is received properly because there is no feedback.The command is then followed by a different pattern, I assume this is some sort of "end of command" string which is the same for all groups except the first 6 bits with the group address.So I could dissect each command into bit patterns like double-zero, double-one, 4-times-one, 14-times-zero... and so on. A total of 6 such pattern is needed to compose a command.I made a script for the Arduino than contains subroutines for each bit pattern and a "main" loop that calls the patterns in the sequence that's needed. The pattern scripts are very simple like:for (int i=0; i<4; i++){digitalWrite (12,HIGH);delayMicroseconds (500);digitalWrite (12,LOW);delayMicroseconds (500);}Where "i<4" can be changed in each subroutine to match the number of bits needed.The subroutines are named like "send1111" or "send12x0" so the main program looks like this:send11();send12x0();send11();send00();delayMicroseconds(3200)...and so on...Well as I said before, it works, it is tested, the motor relais are clicking... It may not be the most elegant way since I'm a noob on Arduino and C programming.If someone has a better idea please let me know.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: June 28, 2018, 11:13:09 am
content: Quote from: compet17 on June 28, 2018, 10:21:36 amThat is really cool... or hot... or sunny or shady... or whatever.Good job!

author: sokoloff
author_rank: Super Contributor
timestamp: June 28, 2018, 11:25:05 am
content: I'd go with something more like this (untested as I don't have an Arduino in front of me):(This code sends the lowest significant bit first (right to left) )Code:void sendShade(unsigned int pattern, int numberOfBits, int pin = 12, int microseconds = 500);void sendShade(unsigned int pattern, int numberOfBits, int pin, int microseconds){for (int i = 0; i < numberOfBits; i++) {digitalWrite(pin, pattern&0x0001 ? HIGH : LOW);//Serial.print(pattern&0x0001 ? "1" : "0");delayMicroseconds(microseconds);pattern = pattern >> 1;}//Serial.println("");}void setup() {// Send 101101 to pin 12sendShade(B101101, 6, 12);// Send 12 zeroes to pin 16 with 350 usec delaysendShade(0, 12, 16, 350);// Your examples:// send11();sendShade(B11, 2);// send12x0();sendShade(0, 12);// send11();sendShade(B11, 2);// send00();sendShade(B00, 2);}

author: sokoloff
author_rank: Super Contributor
timestamp: June 28, 2018, 11:38:53 am
content: Quote from: sokoloff on June 28, 2018, 11:25:05 am

author: compet17
author_rank: Regular Contributor
timestamp: June 29, 2018, 08:08:44 am
content: @Sokoloff: This is an interesting approach...I can't find any detailed documentation of this command:QuoteIf I understand that right, theBinary pattern 101101 will be sent bit by bit (6 loops, one for each bit) to pin 12... But what is the purpose of "&0x0001" after the variablepattern?I'd like to understand what's happening here. Where can i find this in the documentation? Is this "use of variables"? Because the digitalWrite command is not explained so detailed...

author: Nusa
author_rank: Super Contributor
timestamp: June 29, 2018, 08:45:45 am
content: Quote from: compet17 on June 29, 2018, 08:08:44 am0x prefix means the following number is in hexadecimal. In this case so it's more obvious that the number is a mask, not because it needs to be in hex.& operator = bitwise AND: B101101 & 0x0001 = 1digitalWrite is a library alternative to writing ports directly:https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/?: is the conditional operator which works much like an in-line if-else:http://www.cplusplus.com/articles/1AUq5Di1/

author: sokoloff
author_rank: Super Contributor
timestamp: June 29, 2018, 09:06:01 am
content: What Nusa said.I’ll expand slightly. That & expression tests whether the lowest bit is set. If it is, it will return 1; if not will be 0. Then the ternary (“question mark colon”) operator will return the first value (before colon) if true (anything non-zero is true) or the second (after colon) if false (zero).So basically if the lowest bit is on, send HIGH otherwise LOW.