Handling Counter Wrap Around

You need to delay a certain amount of time ticks. Easy, right? You can just say:

target=get_ticks()+100;
/* Do some things */
/* wait for target time to pass */
while (get_ticks()<target);

This works fine as long as adding 100 (the delay count) to the current tick counter doesn’t cause an overflow. Remember 100 is 64 hex and consider this 16-bit counter incident (assuming 16 bit math):

target=get_ticks();  // target=0xFFF0
target=target+100;   // target=0054
while (get_ticks()<target);  // get_ticks is FFFE which is not < 54! Immediate fall through

The same problem occurs with any wrap around, regardless of the word size. However, there is an old trick as long as you can do unsigned math. Let’s look at the following cases:

Case A: Current tick=0x0000; target=0x0100

Case B: Current tick=0xFFFE; target=0x00FE

Case C: Current tick=0xFF00; target=0x0000

When you do a subtraction, the top bit will be set if there was a borrow off the end of the word. That is, subtracting 0x0010 from 0x1234 is really the same as subtracting 0x0010 from 0x11234 and and the end you throw away the extra bit at the left. This helps solve our problem. What if you subtracted the target time from the current time?

Let’s consider the case where the tick is just one more than the original current tick:

Case A: 0x0001-0x0100 = 0xFF01

Case B: 0xFFFF-0x00FE= 0xFF01

Case C: 0xFF01-0x0000=0xFF01

And the case where the current tick has wrapped but isn’t up to the target yet (only applies to B):

Case B: 0x0000-0x00FE=0xFF02

Then consider the case when you are one away from matching:

Case A: 0x00FF-0x0100=0xFFFF

Case B: 0x00FD-0x00FE=0xFFFF

Case C: 0xFFFF-0x0000=0xFFFF

Of course, when you hit the target, you get zero. The key takeaway here is that every result will have bit 15 (in this case; the top bit, in general) set until the result matches. This can be fast to implement. For example, here’s a 32-bit timer from an NXP LCP111x delay loop:

// Set up timer 0 
SIM->SCGC6|=SIM_SCGC6_PIT_MASK; 
PIT->MCR=0; 
PIT->CHANNEL[0].LDVAL=0xFFFFFFFF; 
PIT->CHANNEL[0].TCTRL=PIT_TCTRL_TEN_MASK; 
// Ok here's our start time 
counts=PIT->CHANNEL[0].CVAL; 
// do some stuff here and when done 
// compute the target 
count counts=~counts; // convert to count up (this counter runs down) 
counts+=474; // how many ticks before we proceed (40nS per tick + a little overhead) 
do { clock=~PIT->CHANNEL[0].CVAL; // again, convert to up count 
 } while (clock-counts>=0x80000000UL); // could do a bit test here as well (e.g., while (clock_counts[31]);

 

Naturally, there are other ways to solve this. If the timer isn’t used for anything else, I could have preloaded it and waited for it to hit zero, but that’s not always an option.

Easy mbed Programming from Linux

If you use mbed you know it is cool not to have to install compilers or build libraries and toolchains. You just enter some code, grab some up to date libraries and press compile. Everything runs in your browser and you download a binary file with your program in it. However, you still have to get it to the board. Most of the Arm boards look like a USB drive and you can simply copy or move the file over to do a program. However, I get tired of manually doing that step. This is especially a problem if you use a GUI. You have to remember to move and not copy (so your browser doesn’t keep renaming the file) and you also need to keep confirming the overwrite on the phantom file still on the “fake” USB drive.
So instead, I write a little command line “script” to do it all for me. You could use inotify, but this is easy and I just do it when I’m developing and stop it when I’m done. Suppose your object file is XXX.bin and you are in the /tmp/mbed directory.

Open a shell and go to the /tmp/mbed directory. In my case, the fake USB drive is at /media/USER/FRDM-KL25Z. Then enter this:

while true
 do if [ - f XXX.bin ]
 then echo Programming
 sleep 1
 mv -f XXX.bin /media/USER/FRDM-KL25Z 
 echo Done
 fi
 sleep 2
done

Now when you save your binary file to /tmp/mbed, it will automatically program the device. Simple!

Quick Qt5 Example for GP3

I noticed Qt5 has a QtSerialPort class. Here’s a simple example of talking to the GP3  using this library:

 

    static int state=0;
    QSerialPort port("ttyUSB8",this);  // works with /dev/ttyUSB8 or ttyUSB8
    qDebug()<<port.setBaudRate(QSerialPort::Baud57600);
    qDebug()<<port.open(QIODevice::ReadWrite);
    qDebug()<<port.write(state?"\x0C":"\x0D",1);  // Turns on/off light
    state^=1;
    port.waitForBytesWritten(1000);
    port.close();

Pretty simple. You can read data back either blocking or using slots. I’ll cook up an example of that later.

How to Solve Extruder Skipping

If you hear clicking when filament is moving in your printer, it may be that your extruder is skipping. This isn’t always a big issue, but it does upset the flow rate so your prints are probably not as good as they could be if you are skipping. In extreme cases, it can ruin the print and could even damage your extruder. So what causes it?

The short answer is that the extruder skips because the stepper motor can’t produce enough torque to move the filament the requested amount over the requested period of time. Practically, though, the question is why does this happen and how do you fix it.

There are four basic reasons you might get an extrusion skip: jams, mechanical issues, electrical issues, and software issues. Some of these issues are interrelated so you might divide them up differently than I do.

Jams are usually caused by some obstruction in the path of the filament. Sometimes, it is the filament itself getting kinked. Binding in the feed (for example, a tangled spool) is another common cause. Cheap filament may be bulged out. However, there is another source of obstruction: your misaligned bed. If the nozzle gets too tight against the bed, plastic can’t flow, pressure builds up, and skips will occur. If you can hear skipping when the nozzle is not all the way down, this isn’t your problem (or, at least, it isn’t your only problem). If you get skips uniformly on the first layer, but not later, the whole bed may be too high. If you get skips only on the first layer in a certain area, the bed may be tilted (although some printers automatically deal with that).  The solution is to clear the jam, where ever it is. If it is bed related, get the bed height correct and flat. If you are extruding at too low of a temperature, the plastic is harder to flow and again you may build up enough pressure to skip.

Another possible cause of bulging filament can occur if the plastic gets squashed at the point it is being grabbed. Pretty much all extruders have some kind of gear or hobbed bolt or pinch roller that grabs the plastic and pushes through some kind of hole or tube. If this pinch point is too tight, you can flatten the filament making it too fat to feed. Another possible issue is if the filament is getting hot over time because your hot end isn’t insulated well or your extruder motor is getting hot and the plastic is becoming soft enough to get pinched even though the pinch pressure isn’t very high. Some extruders can even be adjusted so the pinch is too tight for the motor to feed through. If skipping occurs after a long time, you could be getting a soft spot.

Mechanically, you can have a few issues. I mentioned that there is usually some kind of pinch mechanism and a path for the filament to flow. All of this stuff has to be aligned pretty closely or you get binding (which is a kind of a jam). Your hot end needs to line up with the other end of that hole or tube, too. One thing that is easy to overlook is the speed of the extruder. If you try to move plastic too fast, the gear may just slip. Printing fast, printing high volumes (e.g., thick layers), or having too high of a setting on E steps can lead to this. I had this problem recently when I switched from a geared extruder to a direct drive one. Even though I recalibrated the extruder for printing, I forgot the same number is in the printer’s default EEPROM settings. Starting the printer up and manually extruding was a disaster, but prints worked well and after a print, the manual extrusion would be ok. The default speed was just too fast for the direct drive extruder to handle (the geared one needed the faster motor turn to get a slower speed through the gear box).

Electrically, you need to be sure the servo has the right amount of current flowing. Most printer boards have some way to adjust the servo current. If the servo is cool to the touch after a good print setting and you are skipping, you may need to increase the current. If the servo is very hot after a few minutes of printing you may need to decrease the current. A hot motor can cause skipping, so this is a case of where more is not more and less is not more. Just enough is more.

The same holds true for software. You need to have an accurate extruder calibration. Like I mentioned before, spinning too fast will cause the extruder to slip. High acceleration can be the culprit as well.

So how can you bundle all this up into a reasonable check list?

1. Start with the head well away from the bed. If you manually extrude filament do you get skipping? If so, check the temperature, the filament path, or the calibration.

2. Notice if the skipping only occurs at certain places consistently. This could be where you bed has “bumps” or (in a case it took me a while to figure out) that the extruder stepper motor cable is intermittent and those locations put stress on the wire in the right way to break the connection. If it skipping mostly on one corner or one side, suspect bed leveling. Level the bed if necessary. Note this doesn’t really mean to get the bed level to the ground. It means the bed must be parallel to the movement of the print head.

3. If you don’t have extrusion on the first layer at all, then almost certainly the Z height is too low. Readjust your Z height.

4. If all else fails, try raising temperature and lowering speeds. Try a different material. Adjust the drive current to the extruder stepper, if necessary.

 

A Cheap 3D Printing Spool Holder

DSC08268Do you need a simple way to hold a spool of 3D printing filament while printing? A common 12″ bar clamp will do the trick for many workspaces. Just clamp it to your work bench so that the bar is parallel with the ground and slip the spool over the remaining bar. You can use a piece of filament through the hole on the end or a clamp (as shown in the photo) to keep the spool from walking off the end of the bar.

To reduce the friction on the spool, I printed a small tube that I put over the bar so the spool rests on the tube instead of the rectangular bar but, honestly, I don’t see that it makes much difference.

 

 

Pithos (Pandora) Quicklist for Unity or Icon-Only Task Manager

I use KDE but recently installed the excellent Icon-Only Task Manager (http://kde-look.org/content/show.php?content=144808) that lets you set up a Unity-like desktop. One cool thing is that some programs have QuickLists. So if you right click on a Chrome icon, for example, it gives you options to open a new window or tab, etc.

Making a new Quicklist is pretty easy and I use Pithos (http://kevinmehall.net/p/pithos/) quite a bit to listen to Pandora. So here’s my Quicklist for Pithos. Save it as pithos.desktop and put it in /usr/share/applications/pithos.desktop.

[Desktop Entry]
Name=Pithos
Comment=Play music from Pandora Radio
Categories=GNOME;AudioVideo;Player;
Exec=pithos
Icon=pithos
Terminal=false
Type=Application
Actions=Like;Ban;Skip;Pause-Play;

[Desktop Action Like]
Name=Like Song
Exec=qdbus org.mpris.MediaPlayer2.pithos /net/kevinmehall/Pithos net.kevinmehall.Pithos.LoveCurrentSong

[Desktop Action Ban]
Name=Ban Song
Exec=qdbus org.mpris.MediaPlayer2.pithos /net/kevinmehall/Pithos net.kevinmehall.Pithos.BanCurrentSong

[Desktop Action Skip]
Name=Skip Song
Exec=qdbus org.mpris.MediaPlayer2.pithos /net/kevinmehall/Pithos net.kevinmehall.Pithos.SkipSong

[Desktop Action Pause-Play]
Name=Play/Pause
Exec=qdbus org.mpris.MediaPlayer2.pithos /net/kevinmehall/Pithos net.kevinmehall.Pithos.PlayPause

Calibre Leaving Old News on My Sony Reader — Delete It!

I haven’t had much use for book readers, but I saw a Sony PRS-300 in the Sony Outlet Store for only $40 so I bought it. No Linux software, but it does work well with Calibre, so I’ve been very happy with it. It is tiny and has amazing battery life and it is a great alternative to lugging my tablet around all the time.

Calibre has a great feature where it can grab things off the Web, make them into eBooks and put them on your device. They have lots of precreated feeds like the BBC, CNN, etc. There is an option to tell Calibre to remove the news after it is a certain number of days old.

I thought this wasn’t working because stuff was accumulating on my device. However, a little research showed that it is a quirk of Calibre. It removes the news from your library but not the Reader! Oops.

I decided I can run a little script to trim old news from the reader. I may change the Calibre shortcut to do this automatically before it runs Calibre in the future. Here’s the script in case you find it useful:

NOTE: DO NOT USE THIS CODE, use the code below!

#!/bin/bash
# Detele old news files from Sony Reader
# Usage: trimsony [days]
# Default is 5 days (delete things older than 5 days)
echo NO DON'T USE THIS!!!
exit 0

# Check this file to see that reader is connected
READERPRESENTFILE=/media/READER/metadata.calibre
# Directory that holds news
MEDIADIR=/media/READER/database/media/books/News

if [ ! -f $READERPRESENTFILE ]
then
echo Error: Reader not connected! 2>&1
exit 1
fi
DAYS=5
if [ "$1" != "" ]
then
DAYS=$1
fi
# All subscriptions are in /media/READER/database/media/books/News
find $MEDIADIR -type f -mtime +$DAYS -exec rm {} \;
exit 0

You can change the directories and the number of days used by default pretty easily if you like.

Enjoy!

UPDATE: I’m not so sure this is a good idea anymore. I have to run more tests. It does work, but I think deleting files off the Sony makes its media.xml database get out of sync and I can’t figure out what syncs it. Sometimes Calibre gets the dreaded media.xml is corrupt message and then getting it to stop doing that is a massive inconvenience. I’m still looking into it, but be warned!

Update 2: Ok I’m back to try again. I found Calibre has a poorly-documented ebook-device command that lets you do command line operations. I also used kdialog to give a progress bar because it is slow. That means you need kdialog, qdbus, and other stuff that you already have if you are running KDE. However, you could remove that or replace it with other things if you aren’t.


#!/bin/bash
# Detele old news files from Sony Reader
# Usage: trimsony [days]
# Default is 5 days (delete things older than 5 days)

# Mount directory (no trailing slash please)
MOUNT=/media/READER
# Check this file to see that reader is connected
READERPRESENTFILE=$MOUNT/metadata.calibre
# Directory that holds news
MEDIADIR=$MOUNT/database/media/books/News

if [ "$1" == '-' ]
then
dbusRef=$2
CT=`qdbus $dbusRef Get "" value`
CT=`expr $CT + 1`
qdbus $dbusRef Set "" value $CT
BASE=`basename "$3"`
qdbus $dbusRef setLabelText "Removing $BASE"
FILE="${3##$MOUNT}"
echo -n $FILE
ebook-device rm "$FILE"
exit 0
fi

if [ ! -f $READERPRESENTFILE ]
then
echo Error: Reader not connected! 2>&1
exit 1
fi
DAYS=5
if [ "$1" != "" ]
then
DAYS=$1
fi
# All subscriptions are in /media/READER/database/media/books/News
COUNT=`find $MEDIADIR -type f -mtime +$DAYS | wc -l`
if [ "$COUNT" != 0 ]
then
# this desyncs the database!
#find $MEDIADIR -type f -mtime +$DAYS -exec rm {} \;
dbusRef=`kdialog --progressbar "Deleting old news" $COUNT`
qdbus $dbusRef Set "" value 0
find $MEDIADIR -type f -mtime +$DAYS -exec $0 - "$dbusRef" "{}" \;
qdbus $dbusRef close
fi
exit 0

Byobu (Advanced GNU Screen) under Centos 5/Python 2.4

I recently discovered Byobu, which is a set of scripts that lets you use GNU Screen more easily. If you spend a lot of time ssh’d into a server, you should definitely check it out. It worked fine on my desktop machine, but on my Centos 5 server, not so much. I did a little research and I found there were two problems.

The easy problem was keeping F2-F4 from working. The trick is that /etc/screenrc has the following line in it:

termcapinfo xterm 'k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~'

Commenting out the line make the function keys work! That was easy.

The 2nd problem was that F9 was not bringing up the menu. Well, most of the time. Sometimes you could get a peek of a Python traceback and sometimes — not often — it would work. The real puzzle was that if you started byobu-config from the command line it worked fine.

It turns out Centos has Python 2.4 which is pretty old. I intercepted stderr from the script and found out that a command that was reading from a pipe was returning “System Call Interrupted.” This isn’t really an error, but this version of Python apparently thinks it is. So sometimes, that signal wouldn’t interrupt the pipe and it would work.

I tried installing Python 2.6 but there are a lot of dependencies in Centos on Python and although I found someone with a “parallel” RPM it didn’t have the necessary libraries and I finally gave up. But then it hit me. If I could just pause a bit before the offending pipe, the signal would come in — not interrupt the pipe — and then all would be well. It seems to work!

Here’s the fix:

if os.path.exists("%s/.%s/disable-autolaunch" % (HOME, PKG)):
return 0
time.sleep(3)

The script already imports time, so that wasn’t a problem. Problem solved. I like Byobu!

Speeding up Ubuntu Linux with SSDD

A lot of people are switching their Windows machines to boot of solid state disk drives (SSDD) to get faster boot times. The price of these drives has been dropping, but since I use Linux (Kuuntu, actually, which is Ubuntu with KDE) it didn’t make much sense to me. I maybe reboot my machine once a month. What do I care if my reboot time is 30 seconds faster?

Fry’s had a 64GB SSDD on sale this week. After rebate it was around $85 after rebate (you can get roughly the same deal at Newegg). They had a 32GB drive (which had slower specs, too) for even less. So I couldn’t resist. The drive was for a laptop, but the SATA connectors fit. I bought a $4 pair of brackets to make it fit, but in the end since the thing doesn’t spin, I just let it sit on top of a drive tray — I’ll probably secure it later, but for now it is just sitting on the inside. I formatted the whole device with btrfs (no partitions at all) and sure enough I had about 59GB of useful space in a new volume.

I edited fstab to have the line:

UUID=f9f6588e-dc7f-4675-b132-8b008486d243      /ssdd1    btrfs  defaults,ssd,noatime,discard

Of course, your UUID will vary. I had to create /ssdd1 as root and then I did a mount -a to put the drive in place. Now… how to make things go faster?

My basic idea was to copy stuff that KDE, X Windows, etc. uses a lot to the SSDD. I didn’t care so much about user files and I didn’t want the constant writing of /tmp or things from /var (in general) since SSDDs have some limit on write endurance (although modern drives do pretty well if you look into that). And I didn’t want to get messed up with things in /boot or things that I would need if the drive ever failed to mount (/bin, /sbin, and /lib, for example).

What I did was make exact copies of /usr/share, /usr/lib, /usr/bin and put them on /ssdd1/usr/share, and so forth. You have to make exact copies since some things in /usr/bin are suid — that is, they run as their owner and a normal cp won’t do the job (not without a lot of options; look at -p, for example). I used cpio:

find . -print | cpio -admp /ssdd1/usr/bin

Obviously, you need to be root to do that and you need to be in the /usr/bin directory. Once I had the directories in place, I had to move the old directories (I was too chicken to delete them) and link to the new one. Before you do that, though, I’d check that /usr/bin/sudo was in place on the SSDD and that its sticky bit was set. If you lose that and you have no root account set…. well… let’s not do that, ok?

Moving /usr/bin is a little tricky because you need to be root, but sudo is in /usr/bin! The easiest thing to do is just become root even though that angers the Ubuntu faithful:

sudo -i

Then you can do commands like the following:

mv /usr/bin /usr/bin-old ; ln -s /ssdd1/usr/bin /usr/bin

If things go wrong you can still get to things via /usr/bin-old.  So if you do mess up you could do something like:

/usr/bin-old/sudo mv /usr/bin-old /usr/bin

That actually sped things up quite a bit. Booting is notably faster and the response time of X in general is greatly improved.

I then repeated the steps but this time I made shadow directories for ~/.config and ~/.kde. I redirected these to /ssdd1/home/alw/.config and /ssdd1/home/alw/.kde, respectively. This also made the system much snappier.

There are other ways you could have done this. I considered loop mounting over the existing directories, for example. This would be very safe since if the drive didn’t mount you’d just lose performance. The issue is you’d need to occasionally sync the real directory and the shadow directory to be sure any updates were applied. I had bad luck with a scheme like that for putting Firefox’s files into a ram drive — if it does get out of sync, look out. Of course, my scheme has a similar issue — if you lose the SSDD your old files are out of date. But with my setup there is no way for updates to occur to the old files (for example, if the SSDD fails to mount and you don’t notice) making them  mismatched in both directions. You can rsync them from time to time, either way, but with my method if the SSDD fails to mount you will know it immediately. Also, the old files stay visible making syncing them easier if you care to do that.

Meanwhile, I’m happy with how fast this has made my system. Granted, it was fast to start with (8G of RAM, 3.6GHz, and 4 cores), but the system does boot much faster, Gimp loads almost immediately, and switching between tabs in Chrome is notably faster. Since the system files are just moved and not removed, this “update” is fairly safe — you can still get to the original files if you have to. Just remember that updates will not change the old copies.

UPDATE: Turns out Apparmor realizes that things aren’t in /usr/bin anymore and starts blocking things. The only thing I noticed was my printers (the CUPS daemon won’t start). You need to go to /etc/apparmor.d/tunables and edit the alias file. Then reload apparmor and reload affected services (or reboot, which is easier). Here’s mine:

alias /usr/bin/ -> /ssdd1/usr/bin/,
alias /usr/lib/ -> /ssdd1/usr/lib/,
alias /usr/share/ -> /ssdd1/usr/share/,

UPDATE #2: VirtualBox does not like /usr/lib as a symbolic link, I’m not sure why but the code specifically checks for this case and throws an error. I had thought about using bind mounts instead of symlinks before and this pushed me over the edge. So I still use the symlinks for stuff in my home directory but for /usr instead of creating bin, share, and lib links I created empty directories to use as mount points. Then in /etc/fstab I put:

/ssdd1/usr/bin   /usr/bin   bind   defaults,bind   0 0

And similar lines for /usr/share and /usr/lib. Now Apparmor is happy and so is VirtualBox. I assume fstab mounts in order, so be sure those lines come AFTER the mount of /ssdd1, of course.

And one more update: Nepomuk and Strigi — which always give me grief anyway — write huge files to ~/.kde/share/apps/nepomuk/blah blah blah. This will quickly fill up a small SSDD. So one more link. I made ~/.nepomuk and then linked it in the ~/.kde tree. UNFORTUNATELY, filling up a btrfs volume causes it (at least in my case) to become totally unusable and unrepairable. So I would up switching everything to ext4. No compression, but better than having a total crash of the drive when it gets full.

After I had the crash I decided it would be nice if the regular hard drive had a pretty recent copy of what it was supposed to have. Since I had the space full crash about a week after I installed, it wasn’t so bad, but what if it had been a year or more later? Luckily, I had followed a simple pattern to replace the directories. Given some directory I wanted to replace called /x/y/z, I copy it to /ssdd1/x/y/z and then rename the original to /x/y/z-nossdd. Finally a bind mount or symlink points the original location at the SSDD.

Given that pattern, it was easy to create a daily cron job (/etc/cron.daily) named ssdd-backup:

#!/bin/bash
for dir in /home/alw/.kde /opt/google /usr/bin /usr/share /usr/lib /usr/include /usr/lib32 /home/alw/.config /home/alw/.local
do
rsync --archive --update --quiet /ssdd1$dir/ $dir-nossdd
done
This runs every day early in the morning and ensure that the old directories get any updates. The update is NOT two way. If you change something in xxx-nossdd, that does not propagate to the SSDD (but why would you?). Of course, you’ll want to modify the first line to name the directories you actually shadowed.