July 22, 2016

A project log for AquaPic - Aquarium Controller

Reef tank controller used to monitor various parameters such as temp and pH, and also control equipment such as pump and lights.

Skyler BrandtSkyler Brandt 07/23/2016 at 03:030 Comments

I title this picture "So Much Winning!" It has been a reoccurring theme with this build that my RS485 protocol is not functioning as intended but I'm optimistic that a small but somewhat large change will finally end my troubles. There is no longer a 9th bit used for address detection, and thus no longer a need to deal with parity. Backing up a bit, its been a rough road to this point. Just as before, when I thought that I had the communication figured out, my computer goes and updates itself, or I find out that building modules for the Raspberry Pi is an excellent way to make oneself mentally unstable. Back in March I patched the driver for the CH341 driver and had 9bit RS485 communication working on my main computer. However, since then, the CH341 driver has been updated back to kernel default with no parity support. Awesome. Why those few lines of code aren't part of the default driver is kind of dumb in my opinion. However, that wasn't the final nail in parity's coffin and I could re-patch the driver. It isn't difficult, its just a lot of waiting for things to download, and irritation.

My tipping point was attempting to build the CH341 driver for the Raspberry Pi. That was unnecessarily frustrating. I don't know everything I tried, but my bash history is full of thousands of commands I issued in an effort to get one little patch added to a driver. Most of my issues stemmed from the fact that the any compiled CH341 module I built didn't match the version of the Linux kernel itself or some other dependent module. If you don't already know, the header files for the Raspbian kernel are proprietary so there are multiple irritating hoops to jump through to get the exact right branch from Raspberry Pi's Github cloned. There are several forum threads and instructions online that detail ways to get it to work and I tried every one I could find. One person said he had to complete rebuild the entire kernel any time he wanted to update or add a module. That is completely asinine but in a last ditch effort I tried it, and brick the RPi. It still boots but its not right. That was the point when I decided that that 9th bit just wasn't going to happen.

So the question became, what do I do to initiate an address detection. A common RS485 protocol is Modbus, and has two operating modes, ASCII and RTU. ASCII operates just like it sounds and sends ASCII characters. The message is basically a string. 192 would be 0x31, 0x39, 0x32. That mode is initiated, or framed, by sending a semicolon character, ':', to start and a CRLF to end. Simple ASCII characters. The issue with ASCII is that the number of bytes sent in a message can be high, so RTU is used instead. RTU sends the binary representation of message. 192 would be 0xC0. However, start and end framing can't be initiated by a character or number because that number can and will be in the regular message. RTU instead frames its messages with a 3.5 character delay. AquaPic Bus also uses binary messages, so I decided to try framing with a time delay. I thought it was going to be difficult to implement, but it turned out to be fairly easy. Most of the changes happened in the slave code. It has a simple counter that counts up every millisecond but is reset once a byte is received, so that when the serial lines are quiet for at least 10 milliseconds the slave modules start waiting for a address. The next byte is assumed to be the address and if it matches, it handles the message. If it doesn't, it waits for the next delay. The master code was even easier. I simple commented out a few lines and added a 12 millisecond delay before I write out a message. Once I made those few changes, I downloaded the code to the two slave modules, hit debug on the master program, flipped to the AquaPic Bus status window and was met with the glorious sight of "Read/Write was successful". Queue the happy dance. Woo Woo.