Use I2C on raspberry pi with archlinux-arm

For Raspbian there is raspi-config to enable i2c on a raspberry pi. On a system without raspi-config (or if you want to enable i2c on the image before boot) the changes are pretty simple.

The two things raspi-config is changing are:

  • Adding one line to /boot/config.txt:

dtparam=i2c_arm=on
  • Adding one line to /etc/modules-load.d/raspberrypi.conf:

i2c-dev

To get the config and module loaded a reboot of the raspberry pi is necessary.

Then you will problably want to install i2c-tools. For example on archlinux-arm:

pacman -S i2c-tools

And search for i2c sensors plugged in:

i2cdetect -y 1

This could look like this:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 77

The sensors shown here are: ADS1015 (0x48), BME280 (0x76), and BMP180 (0x77).

MNIST with binary color

A few days ago in our local machine learning user group we discussed the decrease of color in MNIST and the possible decrease in accuracy.

To evaluate this I changed the dataloader in the PyTorch MNIST example to change the grayscale color to only black and white:

train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,)),
                       lambda x: x>0,
                       lambda x: x.float(),
            ])),
    batch_size=args.batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../data', train=False, transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,)),
                       lambda x: x>0,
                       lambda x: x.float(),
                   ])),
    batch_size=args.test_batch_size, shuffle=True, **kwargs)

The first lambda binarizes the values in every tensor and the second lambda converts the 0s and 1s to float because the inputs have to be float.

To verify if the datareader modification works I plotted image 7777 from both datareaders:

x, _ = test_loader.dataset[7777]
plt.imshow(x.numpy()[0], cmap='gray')
/images/mnist_5_gray.png/images/mnist_5_bicolor.png
After training with the original loader without any modification for 14 epochs the result for the test set is:
Average loss: 0.0289, Accuracy: 9911/10000 (99%).

With the binary modification in the dataloader the results for the test set is only a bit decreased:
Average loss: 0.0374, Accuracy: 9889/10000 (99%).

Either I missed something or the difference isn't that big.

Org-Mode tables to track progress

I use org-mode tables to track my progress on challenges in Strava.
Of course only the hard to achieve ones, i.e. the "Cycling Climbing Challenge".

Today (2020-02-16) my "February Cycling Climbing Challenge" table looks like this:

|-----+-----+-----+--------------+------|
| 01. | sat |   0 | sum columns: | 2000 |
| 02. | sun |   0 | current:     | 5580 |
| 03. | mon |   0 | total:       | 7580 |
| 04. | tue |   0 | goal:        | 7500 |
| 05. | wed |   0 | missing:     |  -80 |
| 06. | thu |   0 |              |      |
| 07. | fri |   0 |              |      |
| 08. | sat |   0 |              |      |
| 09. | sun |   0 |              |      |
| 10. | mon |   0 |              |      |
| 11. | tue |   0 |              |      |
| 12. | wed |   0 |              |      |
| 13. | thu |   0 |              |      |
| 14. | fri |   0 |              |      |
| 15. | sat |   0 |              |      |
| 16. | sun |   0 |              |      |
| 17. | mon | 200 |              |      |
| 18. | tue | 200 |              |      |
| 19. | wed | 200 |              |      |
| 20. | thu | 200 |              |      |
| 21. | fri | 200 |              |      |
| 22. | sat |   0 |              |      |
| 23. | sun |   0 |              |      |
| 24. | mon | 200 |              |      |
| 25. | tue | 200 |              |      |
| 26. | wed | 200 |              |      |
| 27. | thu | 200 |              |      |
| 28. | fri | 200 |              |      |
| 29. | sat |   0 |              |      |
|-----+-----+-----+--------------+------|
#+TBLFM: @3$5=@1+@2::@1$5=vsum(@<$3..@>$3)::@5$5=@4-@2-@1
This month I already cycled enough weekend tours to reach the goal but only if I cycle to work the remaining days (the workday value is 200 meters).
To update the table I copy the current value manually from the Strava page, set the past days to 0, and update the table (C-u C-c C-c).

There is a lot more possible with the org-mode table editor: https://orgmode.org/manual/Built_002din-Table-Editor.html