Remote Thermostat Update: Getting vgetty working on Raspberry Pi with cheap USB modem

For a little background on this, check out the project requirements. Vgetty should allow me to script in some menus that recognize DTMF tones to run commands. It also appears to support transitioning to a data connection with a specific input code.

The should be perfect for the project once it’s all working. The hard part was finding a modem that would work. I didn’t want to have to get a serial modem that is larger than the Pi, and add a USB-serial converter.

I did some looking around and found this cheap USB modem. Yes, that’s an Amazon affiliate link. Use it if you find this article helpful, but the modem is a TRENDnet TFM-561U if you’d prefer to find it on your own.

Based on the specs it looked like this modem should work, and it does. It uses the Conexant CX93001, so most of this should apply to any of the modems using the CX930xx Series chipset. I ran into some problems with vgetty, but I was able to find a pretty simple solution.

I’ll give the short version for getting it running in Raspbian on the Raspberry Pi, then I’ll fill in some of the details.

Install vgetty and pvftools. Pvftools are used for manipulating the audio files used with the modem, and will be used later.

sudo apt-get install mgetty-voice mgetty-pvftools

Following the vgetty beginners guide, edit /etc/mgetty/voice.conf. There are two important changes to make here, but most of it can be saved for later. The voice device needs to be set for the vm tool, and vgetty needs to be forced to use the V253 modem commands instead of letting it auto-detect.

The first thing to change is in the generic section. The line containing ‘forceV253subset’ needs to be uncommented and changed to true. This is modem dependent, but it may help to get other modems working as well.

forceV253subset TRUE

The second thing to change is in the vm section. The ‘voice_devices’ line needs to be updated to point to the correct device. In this case:

voice_devices ttyACM0

Next a line is added to /etc/inittab to start vgetty. I had to do it a little different than the suggestion, so here’s my completed line:

T3:2345:respawn:/usr/sbin/vgetty ttyACM0

Run ‘sudo init q’ to reload the inittab and vgetty should be running. You can perform some tests and other functions with the vm tool. Try ‘sudo vm help’ to get started with that.

I’ll get to more advanced configuration in another article. If you’re having trouble, or are otherwise interested in how I figured this out, keep reading.

To figure out the tty for the USB modem I ran ‘dmesg | grep tty’ and looked over the results. This line looked right, so I went with it:

cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device

I tried ‘sudo vm devicetest’ and got some promising results, so I went on to try ‘sudo vm beep’. This failed, so I turned up the logging level by setting ‘voice_log_level 6’ in voice.conf. I tried running some of the commands again and checked the logs. I discovered lots of errors from unsupported AT commands.

I realized that vgetty was loading the wrong modem “driver.”  My first reaction was to read through the modem chipset’s manual and dig into vgetty’s source to try to build a new driver for this modem. While I was digging through the source, I realized the ability to force-load generic drivers was built in.

I saw that the ‘AT+IFC’ command could help determine whether to use the V253 or its subset driver. I went ahead and used screen to communicate directly with the modem by typing ‘screen /dev/ttyACM0’. ‘AT+IFC’ returned ERROR, so this modem uses the subset. You can try typing ‘ATI’ and ‘ATIx’ where x is any single digit to see the various responses. Ctrl-a then ‘k’ will kill the session when finished.

After updating voice.conf with ‘forceV253subset TRUE’ I ran the vm devicetest again. It returned some better looking results, but more importantly there were no major errors in the log files. I tried vm beep and actually got a beep through the phone line. If you haven’t restarted or reloaded the inittab by now, do so by running ‘sudo init q’.

With the default settings vgetty should now answer after the specified number of rings, beep, then record a message for up to 5 minutes. If the 5 minute limit is reached it will beep again and save the file. The recording can be stopped by dialing # and the file will still be saved.

The silence and hang-up detection don’t seem to be working with the default settings. The sound quality for recording voice is very bad, but higher pitched tones seem fine. I’m thinking some of these problems are limitations of my test rig, and others are likely configuration problems.

I guess it’s worth noting that I picked up a phone line simulator for testing. You can build your own, buy one, or just use an actual phone line. I got a used Skutch AS-26 for a decent price on ebay.

 Look out for the next post for more on vgetty configuration and scripting.

Improving Efficiency in Rectifier Circuits

I came across an interesting article recently with some information I hadn’t seen yet, so I figured I would share it here. I may be a little behind the times, but I hadn’t looked this closely into power circuits in quite some time.

It seems that there is an improvement over the bridge rectifier, which involves using MOSFETs instead of diodes. There is a little bit of added complexity because it uses a few extra components (resistors and diodes) to trigger the MOSFETs. Since a bridge rectifier can be implemented on a single chip, it still has the benefits of cost and simplicity.

Here’s the article where I found out about it. Definitely something I plan on experimenting with.

Remote Thermostat

Project objective: Develop a thermostat that can be remotely controlled via the PSTN (Public Switched Telephone Network). The thermostat needs to be able to switch between two temperatures in response to a telephone call. The caller will need to input a passcode in order to access the controls.

I had originally planned to build this around the ATMega328 with a DTMF decoder chip and custom-built phone interface circuit using a DAA.

I looked into the approval process for connecting to the PSTN, and it didn’t look that bad. That was until I saw the filing fees. The roughly $1,700 in initial filing fees is a bit excessive for a one-off project, so I decided to take a different route.

Instead of the chip at the heart of the Arduino UNO, I decided to go with the Raspberry Pi Model A+ and use a USB modem for the phone interface. The trick is that the modem will need voice support since I’ll be processing the audio. It also needs to be supported by Linux.

I did a little looking around and found one that seems like it should work. I’m also considering building a circuit to monitor the Pi and trigger a hard reboot if it locks up.

The power for the thermostat was initially going to be drawn from the thermostat relay wiring. These typically run at around 24 VAC.

This system shouldn’t draw much power, but maintaining power while the circuit is closed would be tricky without requiring a common ground for the power supply.

These things considered, it will likely just be powered by an external 5V power supply.

Since the signal wires use A/C I’ll be using some TRIACs for the switching. I took some measurements on my home thermostat. The green-red and yellow-red pairings each drew about 0.5 A. The white-red pairing drew about 0.68 A. These numbers will help me pick out the right parts for the switching circuits, which I will probably design for about 2A draw for plenty of overhead.

Now for a little bit on the software. I’ll likely just run the stock Raspbian or similar since it’s easy to use and gets the job done.

There are two main parts to the software that are needed. The first is the call handling program, and the second is to run the thermostat.

The call handling program needs to answer the modem, then listen for and decode DTMF tones. Once the correct passcode is entered, an informational message should be played.

The caller should then be prompted for action. Based on the input, data should be passed to the thermostat program. Initially this will just be inputting the target temperature.  Solution: vgetty, watch out for an article on getting this working.

The thermostat program just needs to perform simple thermostat functionality and be able to take input from the call program. It should also be able to take direct user input through physical buttons.

Installing distcc on OSX 10.10 Yosemite

I am attempting to do something I haven’t seen done yet, so I figured I would document this here in case someone finds this useful.

I intend to get a distcc server running on OSX Yosemite to compile for various Linux machines. It seems that most people want to do the opposite, but in my case the Mac is the most powerful machine I own.

The first thing I need to do is install distcc. To ease that process I am going to need to get Homebrew working again. I hadn’t attempted to use it since upgrading to Yosemite, but quickly found out that it was no longer working.

I started out with some instructions that I found after a quick search. The problem stems from an updated version of Ruby in Yosemite. This is fixed by modifying one of Homebrew’s files.

It is probably worth noting that I logged in as the superuser to do this, though it should be possible as an administrator by adding ‘sudo’ at the beginning of the console commands.

I modified the brew.rb file as instructed. Here are some quick commands I used:

vim /usr/local/Library/brew.rb

Once in vim, I executed the following commands to change the version reference from 1.8 to current:

:s/1.8/Current/

Then write and quit.

:wq

After doing this, the instructions I used note that you need to commit the changes in brew’s repository. The instructions used $(brew –repository) to get the correct directory, but this didn’t work for me. There was no .git folder in /usr/local/Library/, but I tried the commit there anyway and it worked.

git commit -a -m 'new ruby version 2.0'

Now for the test, I ran brew update and it did failed during a ‘git pull’ with the following error:

Error: Failure while executing: git pull -q origin refs/heads/master:refs/remotes/origin/master

Running brew update again gave the following message, which provided some better clues:

/usr/local/Library/brew.rb:2: syntax error, unexpected <<
<<<<<<< HEAD
^

Editing the brew.rb file again showed some strange stuff in the first few lines. I removed the 3 lines that started with <<<<<, >>>>, and ====. After writing the changes, I committed them again:

git commit -a -m 'fix after update'

Another ‘brew update’ and everything seems to be as it should. Just for good measure I ran brew upgrade and waited for it to finish (been a while since doing this). Now to try installing distcc.

brew install distcc

Seems like it worked; gave the following output:

==> Downloading https://distcc.googlecode.com/files/distcc-3.2rc1.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/distcc/3.2rc1
==> make install
==> Caveats
Use 'brew services start distcc' to start distccd automatically on login.
By default, it will allow access to all clients on 192.168.0.1/24.

To have launchd start distcc at login:
mkdir -p ~/Library/LaunchAgents
ln -sfv /usr/local/opt/distcc/*.plist ~/Library/LaunchAgents
Then to load distcc now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.distcc.plist
==> Summary
/usr/local/Cellar/distcc/3.2rc1: 88 files, 2.1M, built in 23 seconds

That’s it for actually installing distcc. The hard part is going to be creating a cross-compiling environment to accomplish what I want to do.

I’ll be posting a follow-up article going over that part in the future.