Shallow Thoughts

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sat, 09 Dec 2017

Homemade Arduino Part 1: Programming an Atmega328 on a Breadboard

There are lots of tutorials around for building an Arduino on a breadboard, using an Atmega328 (or the older 168) chip, a crystal, a few capacitors and resistors and a power supply. It's a fun project that every Arduino hacker should try at least once.

But while there are lots of instructions on how to wire up a breadboard Arduino, most instructions on how to program one are confusing and incomplete.

Of course, you can program your Atmega chip while it's in an Arduino, then unplug it from the Arduino's socket and move it to the breadboard. But what a hassle! It's so more convenient to leave the chip in the breadboard while you test new versions of the code. And you can, in two different ways: with FTDI, which uses the Arduino bootloader, or with an ISP, which doesn't.

Either way, start by downloading a good pinout diagram for the Atmega328 chip. I use this one: the Arduino ATmega328 Pinout from HobbyTronics, which is very compact yet does a good job of including both the mappings to Arduino digital and analog pins and the functions like RX, TX, MOSI and MISO you'll need for programming the chip.

Load Programs with FTDI

[Circuit for Atmega328 on breadboard with FTDI friend] An FTDI board is a little trickier to wire than an ISP, but it's less risky because it loads the code the same way an Arduino would, so you don't overwrite the bootloader and you can still put your chip back into an Arduino if things go wrong. So let's start with FTDI.

I use an Adafruit "FTDI Friend", but there are lots of similar FTDI boards from Sparkfun and other vendors. They have six outputs, but you'll need only five of those. Referring to your Atmega pinout, wire up power, ground, TX, and RX. For some FTDI boards you may need pullup resistors on the TX and RX lines; I didn't need them.

Now you have four pins connected. Wiring the reset line is more complicated because it requires a 0.1μF capacitor. A lot of tutorials don't mention the capacitor, but it didn't work for me without one. Connect from RTS on the FTDI board, through the 0.1μF cap, to the RST line.

A 0.1μF capacitor is an electrolytic cap with a positive and a negative lead, but the few online tutorials that even mention the capacitor don't bother to say which side is whick. I connected the FTDI friend to the cap's negative lead, and the positive lead to the Atmega chip, and it worked.

You may also need a pullup on that RST/RTS line: a resistor around 10kΩ from the RST pin 1 of the atmega chip to the 5v power line. Note: the Fritzing diagram here shows pullup resistors on RST, TX and RX. You may not need any of them.

Incidentally, RST stands for "reset", while RTS stands for "Ready To Send"; they're not meant as anagrams of each other. The remaining pin on the FTDI friend, CTS, is "Clear To Send" and isn't needed for an Arduino.

Once the wiring is ready, plug in the FTDI board, check to make sure Port is set to whatever port the FTDI board registered, and try uploading a program as if you were uploading to a normal Arduino Uno. And cross your fingers. If it doesn't work, try fiddling with pullups and capacitor values.

Load Programs with an ISP

[Circuit for Atmega328 on breadboard with ISP] An In-System Programmer, or ISP, writes programs straight to the chip, bypassing (and overwriting) the Arduino bootloader. You can also use an ISP to burn a new bootloader and reprogram the fuses on your Arduino, to change parameters like the clock rate. (More on that in Part 2.)

You can use an Arduino as an ISP, but it's somewhat unreliable and prone to unexplained errors. A dedicated ISP isn't expensive, is easier to wire and is more likely to work. A common type of ISP is called a "USBtinyISP", and you can buy one from vendors like Sparkfun or Adafruit, or search for usbtinyisp on sites like ebay or aliexpress.

Arduino ISP pinout ISPs typically use a six-pin connector (2x3). It's not always easy to figure out which end is which, so use a multimeter in continuity mode to figure out which pin is ground. Once you're sure, mark your connector so you'll know which pin is pin 1 (MISO, the pin opposite ground).

Once you have your ISP pins straight, refer to your handy-dandy Atmega328 pinout and connect power, ground, MOSI, MISO, SCK, and RST to the appropriate Atmega pins.

All wired up? In the Arduino IDE, set Programmer to your ISP, for instance, USBtinyISP or Arduino as ISP Then use the Upload button to upload sketches. If you prefer Arduino-mk instead of the IDE, add this to your Makefile:

ISP_PROG     = usbtiny
(or whatever ISP you're using). Then type make ispload instead of make upload

Once you have your FTDI or ISP working, then you can think about making an even simpler circuit -- without the external clock and its associated capacitors. But there are a couple of additional tricks to that. Stay tuned for Part 2.

Tags: ,
[ 15:44 Dec 09, 2017    More hardware | permalink to this entry | comments ]

Mon, 04 Dec 2017

Los Alamos Raspberry Pi Club Starting Up Thursday

[Raspberry Pi Zero W with LED] Are you interested in all things Raspberry Pi, or just curious about them? Come join like-minded people this Thursday at 7pm for the inaugural meeting of the Los Alamos Raspberry Pi club!

At Los Alamos Makers, we've had the Coder Dojo for Teens going on for over a year now, but there haven't been any comparable programs that welcomes adults. Pi club is open to all ages.

The format will be similar to Coder Dojo: no lectures or formal presentations, just a bunch of people with similar interests. Bring a project you're working on, see what other people are working on, ask questions, answer questions, trade ideas and share knowledge.

Bring your own Pi if you like, or try out one of the Pi 3 workstations Los Alamos Makers has set up. (If you use one of the workstations there, I recommend bringing a USB stick so you can save your work to take home.)

Although the group is officially for Raspberry Pi hacking, I'm sure many attendees will interested in Arduino or other microcontrollers, or Beaglebones or other tiny Linux computers; conversation and projects along those lines will be welcome.

Beginners are welcome too. You don't have to own a Pi, know a resistor from a capacitor, or know anything about programming. I've been asked a few times about where an adult can learn to program. The Raspberry Pi was originally introduced as a fun way to teach schoolchildren to program computers, and it includes programming resources suitable to all ages and abilities. If you want to learn programming on your own laptop rather than a Raspberry Pi, we won't turn you away.

Raspberry Pi Club: Thursdays, 7pm, at Los Alamos Makers, 3540 Orange Street (the old PEEC location), Suite LV1 (the farthest door from the parking lot -- look for the "elevated walkway" painted outside the door).

There's a Facebook event: Raspberry Pi club on Facebook. We have meetings scheduled for the next few Thursdays: December 7, 14, and 21, and after that we'll decide based on interest.

Tags: , , ,
[ 10:44 Dec 04, 2017    More hardware | permalink to this entry | comments ]

Wed, 29 Nov 2017

Programming an ATtiny85, Part 2: With the Arduino Software (and a Makefile)

Having written a basic blink program in C for my ATtiny85 with a USBtinyISP (Part 1), I wanted to use it to control other types of hardware. That meant I wanted to be able to use Arduino libraries.

The Arduino IDE

I normally use Makefiles, but the Arduino IDE is much better supported so I tried that first. I followed the steps at High-Low Tech: Programming an ATtiny w/ Arduino 1.6 (or 1.0). But the short summary is:

In Tools->Programmer, choose the programmer you're using (for example, USBtinyISP).

Now you should be able to Verify and Upload a blink sketch just like you would to a regular Arduino, subject to the pin limitations of the ATTiny.

That worked for blink. But it didn't work when I started adding libraries. Since the command-line was what I really cared about, I moved on rather than worrying about libraries just yet.

ATtiny with Arduino-Makefile

For most of my Arduino development I use an excellent package called Arduino-Makefile. There's a Debian package called arduino-mk that works fine for normal Arduinos, but for ATtiny, there have been changes, so use the version from git. A minimal blink Makefile looks like this:

BOARD_TAG = uno
include /usr/share/arduino/Arduino.mk

It assumes that if you're in a directory called blink, it should compile a file called blink.ino. It will also build any additional .cpp files it finds there. make upload uploads the code to a normal Arduino.

With Attiny it gets quite a bit more complicated. The key is that you have to specify an alternate core:

ALTERNATE_CORE = ATTinyCore

But there are lots of different ATtiny cores, they're all different, and they each need a different set of specifiers like BOARD_TAG in the Makefile. Arduino-Makefile comes with an example, but it isn't very useful since it doesn't say where to get the cores that correspond with the various samples. I ended up filing a documentation bug and exchanging some back-and-forth with the maintainer of the package, Simon John, and here's what I learned.

First: as I mentioned earlier, you should use the latest git version of Arduino-Makefile. The version in Debian is a little older and some things have changed; while the older version can be made to work with ATtiny, the recipes will be different from the ones here.

Second, the recipes for each core will be different depending on which version of the Arduino software you're using. Simon says he sticks to version 1.0.5 when he uses ATtinys, because newer versions don't work as well. That may be smart (certainly he has a lot more experience than I do), but I'm always hesitant to rely on software that old, so I wanted to get things working with the latest Arduino, 1.8.5, if i could, so that's what the recipes here will reflect.

Third, as mentioned in Part 1, clock rate should be 1MHz, not 8MHz as you'll see in a lot of web examples, so: F_CPU = 1000000L

Fourth, uploading sketches. As mentioned in the last article, I'm using a USBtinyISP. For that, I use ISP_PROG = usbtiny and sketches are uploaded by typing make ispload rather than the usual make upload. change that if you're usinga different programmer.

With those preliminaries over: I ended up getting two different cores working, and there were two that didn't work. Install the cores in subdirectories in your ~/sketchbook/hardware directory. You can have multiple cores installed at once if you want to test different cores. Here are the recipes.

CodingBadly's arduino-tiny

This is the core that Simon says he prefers, so it's the one I'm going to use as my default. It's at https://github.com/Coding-Badly/arduino-tiny.git, and also a version on Google Code. (Neither one has been updated since 2013.)

git clone it into your sketchbook/hardware. Then either cp 'Prospective Boards.txt' boards.txt or create a new boards.txt and copy from 'Prospective Boards.txt' all the boards you're interested in (for instance, all the attiny85 definitions if attiny85 is the only attiny board you have).

Then your Makefile should look something like this:

ARDUINO_DIR = /path/to/arduino-1.8.5

BOARD_TAG = attiny85at8
ALTERNATE_CORE = tiny
F_CPU = 1000000L
ISP_PROG = usbtiny

include /path/to/Arduino-Makefile/Arduino.mk

If your Arduino software is installed in /usr/share/arduino you can omit the first line.

Now copy blink.ino -- of course, you'll have to change pin 13 to be something between 1 and 6 since that's how many pins an ATtiny has -- and try make and make ispload.

SpenceKonde's ATTinyCore

This core is at https://github.com/SpenceKonde/ATTinyCore.git. I didn't need to copy boards.txt or make any other changes, just clone it under sketches/hardware and then use this Makefile:

ARDUINO_DIR = /path/to/arduino-1.8.5

ALTERNATE_CORE = ATTinyCore
BOARD_TAG = attinyx5
BOARD_SUB = 85
F_CPU = 1000000L
ISP_PROG = usbtiny

include /path/to/Arduino-Makefile/Arduino.mk

Non-working Cores

There are plenty of other ATtiny cores around. Here are two that apparently worked once, but I couldn't get them working with the current version of the tools. I'll omit links to them to try to reduce the probability of search engines linking to them rather than to the more up-to-date cores.

Damellis's attiny (you may see this referred to as HLT after the domain name, "Highlowtech"), on GitHub as damellis/attiny, was the first core I got working with Debian's older version of arduino-mk and Arduino 1.8.4. But when I upgraded to the latest Arduino-Makefile and Arduino 1.8.5, it no longer worked. Ironic since an older version of it was the one used in most of the tutorials I found for using ATtiny with the Arduino IDE. Simon says this core is buggy: in particular, there are problems with software PWM.

I also tried rexxar-tc's arduino-tiny.core2 (also on GitHub). I couldn't get it to work with any of the Makefile or Arduino versions I tried, though it may have worked with Arduino 1.0.

With two working cores, I can get an LED to blink. But libraries are the point of using the Arduino framework ... and as I tried to move beyond blink.ino, I found that not all Arduino libraries work with ATtiny. In particular, Wire, used for protocols like I2C to talk to all kinds of useful chips, doesn't work without substantial revisions. But that's a whole separate topic. Stay tuned.

Tags: , ,
[ 19:06 Nov 29, 2017    More hardware | permalink to this entry | comments ]

Sun, 26 Nov 2017

Reading an IR Remote on a Raspberry Pi Stretch with LIRC

I wrote earlier about how to use an IR remote on Raspbian Jessie.

It turns out several things have changed under Raspbian Stretch. Here's the abbreviated procedure for Stretch:

Install LIRC

$ sudo apt-get install lirc

Enable the LIRC Overlay

Eedit /boot/config.txt as root, look for this line and uncomment it:

# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi
Or if you prefer to use a pin other than 18, change the pin assignment like this:
# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi,gpio_in_pin=25,gpio_out_pin=17

See /boot/overlays/README for more information on overlays.

Fix the LIRC Options

Edit /etc/lirc/lirc_options.conf, comment out the existing driver and device lines, and add:

driver    = default
device = /dev/lirc0

Reboot and stop the daemon

Reboot the Pi.

Now a bunch of LIRC daemons will be running. You don't want them while you're configuring, and if you're eventually going to be reading button presses from Python, you don't want them at all.

Disable them temporarily with

sudo systemctl stop lircd
which seems to be shorthand for
sudo systemctl stop lircd.socket
sudo systemctl stop lircd.service

Be sure to check with ps aux | grep lirc to make sure you've turned them off.

If you want to disable them permanently,

sudo systemctl disable lircd.socket lircd.service lircd-setup.service lircd-uinput.service lircmd.service
I got that list from:
systemctl list-unit-files | grep lirc

But you need them if you want to read from the /var/run/lirc/lircd socket.

Use mode2 to verify it sees the buttons

With the daemons not running, a program called mode2 can verify that your device's buttons are being seen at all. I have no idea why it's named that, or what Mode 1 is.
mode2 -d /dev/lirc0

You should see lots of output. If you don't, double-check your wiring and everything else you've done up to now.

Set up an lircd.conf

Here's where it gets difficult. On Jessie, you could run irrecord -d /dev/lirc0 ~/lircd.conf as described in my earlier article.

However, that doesn't work on stretch. There's apparently a bug in the irrecord in stretch that makes it generate a file that doesn't work. If you try it and it doesn't work, run tail -f /var/log/messages | grep lirc and you may see Info: Cannot configure the rc device for /dev/lirc0 and when you press buttons you'll see Notice: repeat code without last_code received but you won't get any keys.

If you have a working lirc setup from a Jessie machine, try it first. If it doesn't work, there's a script you can try that converts older lirc conf files to a newer format. The safest way to try it is to copy (with cp -a) the whole /etc/lirc directory to a local directory and run:

/usr/share/lirc/lirc-old2new your-local-copy
Or if you feel brave, back up /etc/lirc and run sudo /usr/share/lirc/lirc-old2new with no arguments. Either way, you should get an lirc.conf that has a chance of working with stretch.

If you don't have a working Jessie config, you're in trouble. You might be able to edit the one from irrecord to make it work. Here's the first part of my working Jessie lircd.conf:

begin remote

  name  /home/pi/lircd.conf
  bits           16
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9117  4494
  one           569  1703
  zero          569   568
  ptrail        575
  repeat       9110  2225
  pre_data_bits   16
  pre_data       0xFD
  gap          108337
  toggle_bit_mask 0x0

      begin codes
          KEY_POWER                0x00FF
          KEY_VOLUMEUP             0x807F
          KEY_STOP                 0x40BF
          KEY_BACK                 0x20DF
          KEY_PLAYPAUSE            0xA05F
          KEY_FORWARD              0x609F
          KEY_DOWN                 0x10EF
and here's the corresponding part of the nonworking one generated on Stretch:
begin remote

  name  DingMai
  bits           32
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9117  4494
  one           569  1703
  zero          569   568
  ptrail        575
  repeat       9110  2225
  gap          108337
  toggle_bit_mask 0x0
  frequency    38000

      begin codes
          KEY_POWER                0x00FD00FF 0xBED8F1BC
          KEY_VOLUMEUP             0x00FD807F 0xBED8F1BC
          KEY_STOP                 0x00FD40BF 0xBED8F1BC
          KEY_BACK                 0x00FD20DF 0xBED8F1BC
          KEY_PLAYPAUSE            0x00FDA05F 0xBED8F1BC
          KEY_FORWARD              0x00FD609F 0xBED8F1BC
          KEY_DOWN                 0x00FD10EF 0xBED8F1BC

It looks like setting bits to 16 and then using the second quartet from each key might work. So try that if you're stuck.

Once you get irw working, you're home free. The Python modules probably still won't do anything useful, but you can use my pyirw.py script as a model for a simple way to read keys from the lirc daemon.

In case you hit problems beyond what I saw, I found this discussion useful, which links to a complete GitHub gist of instructions for setting up lirc on Stretch. Those instructions have a couple of extra steps involving module loading that it turned out I didn't need, and on the other hand it doesn't address the problems I saw with irrecord. It looks like lirc configuration is a black art, not a science. See what works for you. Good luck!

Tags: , ,
[ 12:00 Nov 26, 2017    More hardware | permalink to this entry | comments ]

Thu, 02 Nov 2017

Programming an ATtiny85, Part 1: Using C with a USBtinyISP

[ATtiny85 and USBtinyISP programmer] Arduinos are great for prototyping, but for a small, low-power, cheap and simple design, an ATtiny chip seems like just the ticket. For just a few dollars you can do most of what you could with an Arduino and use a lot of the same code, as long as you can make do with a little less memory and fewer pins.

I've been wanting to try them, and recently I ordered a few ATtiny85 chips. There are quite a few ways to program them. You can buy programmers specifically intended for an ATtiny, but I already had a USBtinyISP, a chip used to program Arduino bootloaders, so that's what I'll discuss here.

Wiring to the USBtinyISP

[ATtiny85 and USBtinyISP wiring] The best reference I found on wiring was Using USBTinyISP to program ATTiny45 and ATTiny85. That's pretty clear, but I made my own Fritzing diagram, with colors, so it'll be easy to reconstruct it next time I need it. The colors I used:
MISO yellow VCC red
SCK white MOSI green
RESET orange
or red/black
GND black

Programming the ATtiny in C

I found a couple of blink examples at electronut.in, Getting Started with ATtiny AVR programming, and in a Stack Exchange thread, How to program an AVR chip in Linux Here's some basic blink code:

#include 
#include 

int main (void)
{
    // Set Data Direction to output on port B, pins 2 and 3:
    DDRB = 0b00001000;
    while (1) {
        // set PB3 high
        PORTB = 0b00001000;
        _delay_ms(500);
        // set PB3 low
        PORTB = 0b00000000;
        _delay_ms(500);
    }

    return 1;
}

Then you need a Makefile. I started with the one linked from the electronut page above. Modify it if you're using a programmer other than a USBtinyISP. make builds the program, and make install loads it to the ATtiny. And, incredibly, my light started blinking, the first time!

[ATtiny85 pinout] Encouraged, I added another LED to make sure I understood. The ATtiny85 has six pins you can use (the other two are power and ground). The pin numbers correspond to the bits in DDRB and PORTB: my LED was on PB3. I added another LED on PB2 and made it alternate with the first one:

    DDRB = 0b00001100;
[ ... ]
        // set PB3 high, PB2 low
        PORTB = 0b00001000;
        _delay_ms(500);
        // set PB3 low, PB2 high
        PORTB = 0b00000100;
        _delay_ms(500);

Timing Woes

But wait -- not everything was rosy. I was calling _delay_ms(500), but it was waiting a lot longer than half a second between flashes. What was wrong?

For some reason, a lot of ATtiny sample code on the web assumes the chip is running at 8MHz. The chip's internal oscillator is indeed 8MHz (though you can also run it with an external crystal at various speeds) -- but its default mode uses that oscillator in "divide by eight" mode, meaning its actual clock rate is 1MHz. But Makefiles you'll find on the web don't take that into account (maybe because they're all copied from the same original source). So, for instance, the Makefile I got from electronut has

CLOCK = 8000000
If I changed that to
CLOCK = 1000000
now my delays were proper milliseconds, as I'd specified. Here's my working attiny85 blink Makefile.

In case you're curious about clock rate, it's specified by what are called fuses, which sound permanent but aren't: they hold their values when the chip loses power, but you can set them over and over. You can read the current fuse settings like this:

avrdude -c usbtiny -p attiny85 -U lfuse:r:-:i -v
which should print something like this:
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)

To figure out what that means, go to the Fuse calculator, scroll down to Current settings and enter the three values you got from avrdude (E, H and L correspond to Extended, High and Low). Then scroll up to Feature configuration to see what the fuse settings correspond to. In my case it was Int. RC Osc. 8 Mhz; Start-up time PWRDWN/RESET; 6CK/14CK+ 64ms; [CKSEL=1011 SUT=10]; default value and Divide clock by 8 internally; [CKDIV8=0] was checked.

More on ports and pins

There's more info on ATtiny ports in ATTiny Port Manipulation (Part 1): PinMode() and DigitalWrite()

Nobody seems to have written much about AVR/ATTINY programming in general. Symbols like PORTB and functions like _delay_ms() come from files in /usr/lib/avr/include/, at least on my Debian system. There's not much there, so if you want library functions to handle nontrivial hardware, you'll have to write them or find them somewhere else.

As for understanding pins, you're supposed to go to the datasheet and read it through, all 234 pages. Hint: for understanding basics of reading from and writing to ports, speed forward to section 10, I/O Ports. A short excerpt from that section:

Three I/O memory address locations are allocated for each port, one each for the Data Register - PORTx, Data Direction Register - DDRx, and the Port Input Pins - PINx. The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the PINx Register, (comma sic) will result in a toggle in the corresponding Data Register. In addition, the Pull-up Disable - PUD bit in MCUCR disables the pull-up function for all pins in all ports when set.

There's also some interesting information there about built-in pull-up resistors and how to activate or deactivate them.

That's helpful, but here's the part I wish they'd said:

PORTB (along with DDRB and PINB) represents all six pins. (Why B? Is there a PORTA? Not as far as I can tell; at least, no PORTA is mentioned in the datasheet.) There are six output pins, corresponding to the six pins on the chip that are not power or ground. Set the bits in DDRB and PORTB to correspond to the pins you want to set. So if you want to use pins 0 through 3 for output, do this:

    DDRB = 0b00001111;

If you want to set logical pins 1 and 3 (corresponding to pins 6 and 2 on the chip) high, and the rest of the pins low, do this:

    PORTB = 0b00001010;

To read from pins, use PINB.

In addition to basic functionality, all the pins have specialized uses, like timers, SPI, ADC and even temperature measurement (see the diagram above). The datasheet goes into more detail about how to get into some of those specialized modes.

But a lot of those specialties are easier to deal with using libraries. And there are a lot more libraries available for the Arduino C++ environment than there are for a bare ATtiny using C. So the next step is to program the ATtiny using Arduino ... which deserves its own article.

Tags: , ,
[ 18:01 Nov 02, 2017    More hardware | permalink to this entry | comments ]

Thu, 26 Oct 2017

Reading an IR Remote on a Raspberry Pi with LIRC

[IR remote with Raspberry Pi Zero W]

Our makerspace got some new Arduino kits that come with a bunch of fun parts I hadn't played with before, including an IR remote and receiver.

The kits are intended for Arduino and there are Arduino libraries to handle it, but I wanted to try it with a Raspberry Pi as well.

It turned out to be much trickier than I expected to read signals from the IR remote in Python on the Pi. There's plenty of discussion online, but most howtos are out of date and don't work, or else they assume you want to use your Pi as a media center and can't be adapted to more general purposes. So here's what I learned.

Update: this page is for Raspbian Jessie. If you've upgraded to Stretch, read the update, Reading an IR Remote on a Raspberry Pi Stretch with LIRC, then come back here and jump forward to Set up a lircd.conf.


Install LIRC and enable the drivers on the Pi

The LIRC package reads and decodes IR signals, so start there:

$ sudo apt-get install lirc python-lirc python3-lirc

Then you have to enable the lirc daemon. Assuming the sensor's pin is on the Pi's GPIO 18, edit /boot/config.txt as root, look for this line and uncomment it:

# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi

Reboot. Then use a program called mode2 to make sure you can read from the remote at all, after first making sure the lirc daemon isn't running:

$ sudo service lirc stop
$ ps aux | grep lirc
$ mode2 -d /dev/lirc0

Press a few keys. If you see a lot of output, you're good. If not, check your wiring.

Set up a lircd.conf

You'll need to make an lircd.conf file mapping the codes the buttons send to symbols like KEY_PLAY. You can do that -- ina somewhat slow and painstaking process -- with irrecord.

First you'll need a list of valid key names. Get that with irrecord -l and you'll probably want to keep that window up so you can search or grep in it. Open another window and run:

$ irrecord -d /dev/lirc0 ~/lircd.conf

I had to repeat the command a couple of times; the first few times it couldn't read anything. But once it's running, then for each key on the remote, first, find the key name that most closely matches what you want the key to do (for instance, if the key is the power button, irrecord -l | grep -i power will suggest KEY_POWER and KEY_POWER2). Type or paste that key name into irrecord -d, then press the key. At the end of this, you should have a ~/lircd.conf.

Some guides say to copy that lircd.conf to /etc/lirc/ andI did, but I'm not sure it matters if you're going to be running your programs as you rather than root.

Then enable the lirc daemon that you stopped back when you were testing with mode2. In /etc/lirc/hardware.conf, START_LIRCMD is commented out, so uncomment it. Then edit /etc/lirc/hardware.conf as specified in alexba.in's "Setting Up LIRC on the RaspberryPi". Now you can start the daemon:

sudo service lirc start
and verify that it's running: ps aux | grep lirc.

Testing with irw

Now it's time to test your lircd.conf:

irw
Press buttons, and hopefully you'll see lines like
0000000000fd8877 01 KEY_2 /home/pi/lircd.conf
0000000000fd08f7 00 KEY_1 /home/pi/lircd.conf
0000000000fd906f 00 KEY_VOLUMEDOWN /home/pi/lircd.conf
0000000000fd906f 01 KEY_VOLUMEDOWN /home/pi/lircd.conf
0000000000fda05f 00 KEY_PLAYPAUSE /home/pi/lircd.conf

If they correspond to the buttons you pressed, your lircd.conf is working.

Reading Button Presses from Python

Now, most tutorials move on to generating a .lircrc file which sets up your machine to execute programs automatically when buttons are pressed, and then you can test with ircat. If you're setting up your Raspberry Pi as a media control center, that's probably what you want (see below for hints if that's your goal). But neither .ircrc nor ircat did anything useful for me, and executing programs is overkill if you just want to read keys from Python.

Python has modules for everything, right? The Raspbian repos have python-lirc, python-pylirc and python3-lirc, and pip has a couple of additional options. But none of the packages I tried actually worked. They all seem to be aimed at setting up media centers and wanted lircrc files without specifying what they need from those files. Even when I set up a .lircrc they didn't work. For instance, in python-lirc, lirc.nextcode() always returned an empty list, [].

I didn't want any of the "execute a program" crap that a .lircrc implies. All I wanted to do was read key symbols one after another -- basically what irw does. So I looked at the irw.c code to see what it did, and it's remarkably simple. It opens a socket and reads from it. So I tried implementing that in Python, and it worked fine: pyirw.py: Read LIRC button input from Python.

While initially debugging, I still saw those

0000000000fda05f 00 KEY_PLAYPAUSE /home/pi/lircd.conf
lines printed on the terminal, but after a reboot they went away, so they might have been an artifact of running irw.

If You Do Want a .lircrc ...

As I mentioned, you don't need a .lircrc just to read keys from the daemon. But if you do want a .lircrc because you're running some sort of media center, I did find two ways of generating one.

There's a bash script called lirc-config-tool floating around that can generate .lircrc files. It's supposed to be included in the lirc package, but for some reason Raspbian's lirc package omits it. You can find and download the bash script witha web search for lirc-config-tool source, and it works fine on Raspbian. It generates a bunch of .lircrc files that correspond to various possible uses of the remote: for instance, you'll get an mplayer.lircrc, a mythtv.lircrc, a vlc.lircrc and so on.

But all those lircrc files lirc-config-tool generates use only small subsets of the keys on my remote, and I wanted one that included everything. So I wrote a quickie script called gen-lircrc.py that takes your lircd.conf as input and generates a simple lircrc containing all the buttons represented there. I wrote it to run a program called "beep" because I was trying to determine if LIRC was doing anything in response to the lircrc (it wasn't); obviously, you should edit the generated .lircrc and change the prog = beep to call your target programs instead.

Once you have a .lircrc, I'm not sure how you get lircd to use it to call those programs. That's left as an exercise for the reader.

Tags: , ,
[ 11:21 Oct 26, 2017    More hardware | permalink to this entry | comments ]

Thu, 12 Oct 2017

Letter to the New Mexico Public Education Department on Science Standards

For those who haven't already read about the issue in the national press, New Mexico's Public Education Department (a body appointed by the governor) has a proposal regarding new science standards for all state schools. The proposal starts with the national Next Generation Science Standards but then makes modifications, omitting points like references to evolution and embryological development or the age of the Earth and adding a slew of NM-specific standards that are mostly sociological rather than scientific.

You can read more background in the Mother Jones article, New Mexico Doesn’t Want Your Kids to Know How Old the Earth Is. Or why it’s getting warmer, including links to the proposed standards. Ars Technica also covered it: Proposed New Mexico science standards edit out basic facts.

New Mexico residents have until 5.p.m. next Monday, October 16, to speak out about the proposal. Email comments to rule.feedback@state.nm.us or send snail mail (it must arrive by Monday) to Jamie Gonzales, Policy Division, New Mexico Public Education Department, Room 101, 300 Don Gaspar Avenue, Santa Fe, New Mexico 87501.

A few excellent letters people have already written:

I'm sure they said it better than I can. But every voice counts -- they'll be counting letters! So here's my letter. If you live in New Mexico, please send your own. It doesn't have to be long: the important thing is that you begin by stating your position on the proposed standards.


Members of the PED:

Please reconsider the proposed New Mexico STEM-Ready Science Standards, and instead, adopt the nationwide Next Generation Science Standards (NGSS) for New Mexico.

With New Mexico schools ranking at the bottom in every national education comparison, and with New Mexico hurting for jobs and having trouble attracting technology companies to our state, we need our students learning rigorous, established science.

The NGSS represents the work of people in 26 states, and is being used without change in 18 states already. It's been well vetted, and there are many lesson plans, textbooks, tests and other educational materials available for it.

The New Mexico Legislature supports NGSS: they passed House Bill 211 in 2017 (vetoed by Governor Martinez) requiring adoption of the NGSS. The PED's own Math and Science Advisory Council (MSAC) supports NGSS: they recommended in 2015 that it be adopted. Why has the PED ignored the legislature and its own advisory council?

Using the NGSS without New Mexico changes will save New Mexico money. The NGSS is freely available. Open source textbooks and lesson plans are already available for the NGSS, and more are coming. In contrast, the New Mexico Stem-Ready standards would be unique to New Mexico: not only would we be left out of free nationwide educational materials, but we'd have to pay to develop New Mexico-specific curricula and textbooks that couldn't be used anywhere else, and the resulting textbooks would cost far more than standard texts. Most of this money would go to publishers in other states.

New Mexico consistently ranks at the bottom in educational comparisons. Yet nearly 15% of the PED's proposed stem-ready standards are New Mexico specific standards, taught nowhere else, and will take time away from teaching core science concepts. Where is the evidence that our state standards would be better than what is taught in other states? Who are we to think we can write better standards than a nationwide coalition?

In addition, some of the changes in the proposed NM STEM-Ready Science Standards seem to be motivated by political ideology, not science. Science standards used in our schools should be based on widely accepted scientific principles. Not to mention that the national coverage on this issue is making our state a laughingstock.

Finally, the lack of transparency in the NMSRSS proposal is alarming. Who came up with the proposed NMSRSS standards? Are there any experts in science education that support them? Is there any data to indicate they'd be more effective than the NGSS? Why wasn't the development of the NMSRSS discussed in open PED meetings as required by the Open Meetings Act?

The NGSS are an established, well regarded national standard. Don't shortchange New Mexico students by teaching them watered-down science. Please discard the New Mexico Stem-Ready proposal and adopt the Next Generation Science Standards, without New Mexico-specific changes.

Tags: , ,
[ 10:16 Oct 12, 2017    More politics | permalink to this entry | comments ]

Thu, 05 Oct 2017

Tarantula Under Glass, and Micro-Centipedes

Every fall, Dave and I eagerly look for tarantulas. They only show up for a few weeks a year -- that's when the males go out searching for females (the females stay snug in their burrows). In the bay area, there were a few parks where we used to hunt for them: Arastradero, Mt Hamilton, occasionally even Alum Rock. Here in semi-rural New Mexico, our back yard is as good a place to hunt as anywhere else, though we still don't see many: just a couple of them a year.

But this year I didn't even have to go out into the yard. I just looked over from my computer and spotted a tarantula climbing up our glass patio door. I didn't know they could do that!

Unfortunately it got to the top before I had the camera ready, so I didn't get a picture of tarantula belly. Right now he's resting on the sill: [Tarantula, resting after climbing up our glass patio door] I don't think it's very likely he's going to find any females up there. I'm hoping he climbs back down the same way and I can catch a photo then. (Later: nope, he disappeared when I wasn't watching.)

In other invertebrate news: we have a sporadic problem with centipedes here in White Rock. Last week, a seven-inch one dropped from the ceiling onto the kitchen floor while I was making cookies, and it took me a few minutes to chase it down so I could toss it outside.

[Tiny baby centipede] But then a few days later, Dave spotted a couple of these little guys on the patio, and I have to admit they're pretty amazing. Just like the adults only in micro-miniature.

Though it doesn't make me like them any better in the house.

Tags: ,
[ 18:47 Oct 05, 2017    More nature | permalink to this entry | comments ]